Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Adaptor usb3.1gigabit vs Adaptor ...

La multi ani @Atreides!

La multi ani @KENSINGTON!

La multi ani @burebista!
 La multi ani de Florii!

Stihl fs 70 c-e

Challengers (2024)

Care mai sunt mediile de admitere...
 Laptop cu HDD atasare memorie MMC...

Hartile google nu mai au chenarul...

Tomate in ghiveci la curte?

Idei cale de actiune recuperare g...
 Intoleranța lactoza- vegan v...

Tobe acustice insonorizare in blo...

Cine canta? Fragment din melodie...

Tablou sigurante Dacia Sandero 2012
 

Muncă multă în constructor - da sau ba?

* * * - - 2 votes
  • Please log in to reply
98 replies to this topic

#1
jegmihai

jegmihai

    Senior Member

  • Grup: Senior Members
  • Posts: 11,536
  • Înscris: 03.09.2013
Salut, purtam o discuție cu un prieten de-al meu legat de subiectul menționat în titlu.

Pe scurt, voi sunteți de acord să faceți "muncă multă" în constructorii obiectelor?

Prin "muncă multă" mă refer la operații specifice IO care iau mult timp sau diverse calcule complexe. De asemenea, haideți să presupunem că această muncă este esențială pentru ca obiectul nostru să fie instanțiat corect (și complet) și gata de utilizare.

Eu prefer varianta cu "muncă multă" în constructor pentru a nu fi nevoit mai apoi să apelez alte metode pentru a aduce obiectul într-o stare validă, mi se pare cea mai safe metodă.

Pe de cealaltă parte, prietenul insistă că un constructor ar trebui să fie rapid în orice circumstanțe și, pe deasupra, să nu arunce excepții. Astfel deducem că va mai fi nevoie de apelarea câtorva metode de genul
object.loadImages(path);

după instanțierea obiectului.

Problema mea principală cu acest approach este următoarea, dacă cineva uită să cheme acea/acele metodă/metode?

Aștept părerile voastre.

#2
Mosotti

Mosotti

    Geniu umil

  • Grup: Senior Members
  • Posts: 33,295
  • Înscris: 21.04.2004
Constructorul trebuie sa fie rapid si orice chestie care dureaza "mult timp" trebuie in primul rind sa nu blocheze aplicatia si in al doilea rind sa ofere un mecanism prin care sa poti urmari progresul / sa poti intrerupe procesul. E prea plin universul de aplicatii in care dai click si se blocheaza tot pina la sfintu-asteapta...

View Postjegmihai, on 29 aprilie 2019 - 12:53, said:

Problema mea principală cu acest approach este următoarea, dacă cineva uită să cheme acea/acele metodă/metode?

Asta e o non-problema, pentru ca incapsularea exista tocmai pentru a putea stii intotdeauna care este starea obiectului.

#3
jegmihai

jegmihai

    Senior Member

  • Grup: Senior Members
  • Posts: 11,536
  • Înscris: 03.09.2013

View PostMosotti, on 29 aprilie 2019 - 13:09, said:

Constructorul trebuie sa fie rapid si orice chestie care dureaza "mult timp" trebuie in primul rind sa nu blocheze aplicatia
Păi și problema asta nu s-ar rezolva cu cod asincron?

#4
elbjorn

elbjorn

    Senior Member

  • Grup: Senior Members
  • Posts: 3,085
  • Înscris: 02.09.2016

View Postjegmihai, on 29 aprilie 2019 - 12:53, said:

Aștept părerile voastre.
(Filozofia mea), Daca ai nevoie sa explici ideile dintr-o functie/metoda atunci faci alta pe care o numesti corespunzator si ii pui comentariul la summary.
Asta se aplica si la constructor.  

Traim intr-o societate in care puterea de concentrare este in continua scadere (multumim apple, hollywood, etc), iar cei care i-ti vor calca pe urme, foarte probabil sa nu poata intelege o logica prea elaborata.

Si bineinteles, "You should name a variable using the same care with which you name a first-born child.”– James O. Coplien

Edited by elbjorn, 29 April 2019 - 13:41.


#5
Mosotti

Mosotti

    Geniu umil

  • Grup: Senior Members
  • Posts: 33,295
  • Înscris: 21.04.2004

View Postjegmihai, on 29 aprilie 2019 - 13:15, said:

Păi și problema asta nu s-ar rezolva cu cod asincron?
Ok, sa zicem ca tu pui in constructor un calcul de 2 minute si il rulezi asincron. Aplicatia nu se blocheaza, uraaa. Ce faci daca te razgindesti dupa ce dai run pentru ca iti dai seama ca ai gresit un parametru? Astepti 2 minute? Dai kill thread si ciuciu cleanup? Cum ii arati omului cam care e statusul operatiei? Imi aduce aminte de Windoze update. "Windoze is performing an update, it might take several minutes". Meanwhile, 2 hours later...

View Postelbjorn, on 29 aprilie 2019 - 13:40, said:

Traim intr-o societate in care puterea de concentrare este in continua scadere (multumim apple, hollywood, etc), iar cei care i-ti vor calca pe urme, foarte probabil sa nu poata intelege o logica prea elaborata.
Nimeni nu intelege o logica elaborata daca cel care o exprima este debil. :first:

#6
elbjorn

elbjorn

    Senior Member

  • Grup: Senior Members
  • Posts: 3,085
  • Înscris: 02.09.2016

View PostMosotti, on 29 aprilie 2019 - 13:47, said:

Nimeni nu intelege o logica elaborata daca cel care o exprima este debil. Posted Image
Tocmai asta a si fost exercitiul ,)

#7
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Ai două probleme:

- păstrarea obiectului într-un state valid
- viteza


Ambele sunt importante.

Zici că e vorba de IO. Ceva miroase nasol în arhitectura mai largă. Nimeni nu mai scrie/citește din acel IO? Faci locking în constructor?

Detaliile contează.

#8
DemocracySucks

DemocracySucks

    Junior Member

  • Grup: Members
  • Posts: 227
  • Înscris: 06.04.2019
Nu suna bine ce zici tu acolo ... nu prea se face munca in constructor... daca ai niste resurse alea se initializeaza in alta parte si se paseaza ca argumente catre constructor(in mod normal)...

#9
neagu_laurentiu

neagu_laurentiu

    Guru Member

  • Grup: Senior Members
  • Posts: 40,604
  • Înscris: 30.07.2003

View Postjegmihai, on 29 aprilie 2019 - 12:53, said:

Problema mea principală cu acest approach este următoarea, dacă cineva uită să cheme acea/acele metodă/metode?
Pai nu documentezi epopeea? Si cat va uita, pana la primul test. Ajunge in productie cod nefunctional?
Ca extind un pic ce ai spus, ia vezi ce afiseaza in .NET ori Java (in C++ macar se prinde de poveste):
class A
{
	public A()
	{
		Console.WriteLine("A.A");
		f();
	}
	public virtual void f()
	{
		Console.WriteLine("A.f");
		g();
	}
	public virtual void g()
	{
		Console.WriteLine("A.g");
	}
}
class B : A
{
	public B()
	{
		Console.WriteLine("B.B");
	}
	public override void f()
	{
		   
		Console.WriteLine("B.f");
		g();
	}
	public override void g()
	{
		Console.WriteLine("B.g");
	}
}
class Program
{
	static void Main(string[] args)
	{
		A a = new B();
		a.f();
	}
}


Edited by neagu_laurentiu, 29 April 2019 - 15:35.


#10
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,240
  • Înscris: 24.02.2007
Ca tot e vorba de IO, C# de exemplu nu poti beneficia de avantajele async/await in constructor. Deci cade ideea din start.

#11
Iulius-Foyas

Iulius-Foyas

    Active Member

  • Grup: Members
  • Posts: 1,361
  • Înscris: 21.04.2019

View Postjegmihai, on 29 aprilie 2019 - 12:53, said:

Aștept părerile voastre.
Intr-un constructor ar trebui sa pui doar codul suficient pt instantierea obiectului, astlfe risti sa ascunzi detalii importante despre functionarea acelui obiect altor programatori care doresc sa foloseasca
doar functionalitatea A a obiectului iar alt programator doreste sa foloseasca  doar functionalitatea B a obiectului.
Adica:
class MyObject () {
public MyObject(){
//calcul medie aritmetica
//calcul medie geometrica
//calcul medie armonica
}
//getter rezultat medie aritmetica
//getter rezultat medie geometrica
//getter rezultat medie armonica
}


daca programatorul X vrea doar sa-ti foloseasca obiectul  doar pt media aritmetica atunci nu poate ca trebuie fara sa vrea sa calculeze si media geometrica, s.a.m.d
daca programatorul Y vrea doar sa-ti foloseasca obiectul  doar pt media geometrica atunci nu poate ca trebuie fara sa vrea sa calculeze si media aritmetica., s.a.m.d
Insa daca iti rescrii obiectul astfel:
public MyObject(){
  //chestii necesare care doar instanteaza obiectul pt a putea fi folosit
}

//metoda calcul media arittmetica
//metoda calcul media armonica
//metoda calcul media geometrica

//getter rezultat medie aritmetica
//getter rezultat medie geometrica
//getter rezultat medie armonica


Edited by Iulius-Foyas, 30 April 2019 - 00:29.


#12
Iulius-Foyas

Iulius-Foyas

    Active Member

  • Grup: Members
  • Posts: 1,361
  • Înscris: 21.04.2019
Vine programatorul X care iti instantieaza obiectul si isi calculeaza  media geometrica(adica doar ce-i trebuie)
Vine programatorul Y care iti instantieaza obiectul si isi calculeaza media armonica(adica doar ce-i trebuie)
Vine programatorul Z care iti instantieaza obiectul si isi calculeaza media aritmetica(adica doar ce-i trebuie)

de asenmeni daca vrei poti sa realizezi acelasi lucru fie prin supraincarcarea constructorului fie printr-un camp selector:

supraincarcare constructuor
class MyObject() {

public MyObject(Media medie) {
//cod minimal pt instantierea obiectului daca exista
	 this.medie = medie
}

public void printRezultate() {
	 medie.calculeaza();
	 medie.printRezultate();
}
//alte metode etc
}

Interface Media(){
//metoda de introducere a datelor
//metoda de calcul a tipului de medie
//metoda de scoatere a rezultatului
}

class MediaAritmetica implements Medie{
//cod necesar
}

class MediaGeometrica implements Medie{
//cod necesar
}

class MediaArmonica implements Medie{
//cod necesar
}

apoi in cod vine fiecare programator si face:
//programatorul X vrea
MyObject mo = new MyObject(new MedieAritmetica());
mo.printRezultate();
//programatorul Y vrea
MyObject mo = new MyObject(new MedieArmonica());
mo.printRezultate();
//programatorul Z vrea
MyObject mo = new MyObject(new MedieGeometrica());
mo.printRezultate();


selectie printr-un camp selector
class MyObject(){
public MyObject(String selector) {
//cod minimal instantiere obiect
	 this.selector = selector
}
//metoda ce contine cod de calcul pt fiecare medie
public void printRezultate throws SelectieInvalidaExceptie{
	 switch(selector){
		 case "medie_aritmetica":
			 //metoda de calcul a calcul mediei aritmetice;
		 break;
		 case "medie_geometrica":
			 //metoda de calcul a calcul mediei geometrice;
		 break;
		 case "medie_armonica":
			 //metoda de calcul a calcul mediei armonice;
			 break;	
		 case default:
				 throw new SelectieInvalidaExceptie();
				 break;
	 }
}
public SelectieInvalidaExceptie extends Exception{
	  Public SelectieInvalidaExceptie(String mesaj) {
	   super(mesaj)
	 }
}


Apoi fiecare programator poate independent sa faca:
try{
MyObject mo = new MyObject("medie aritmetica");
mo.printRezultate()
}
catch(SelectieInvalidaExceptie eroare){
	 eroare.printStackTrace();
}
finally{
	 //cod aici de inchidere a referintelor IO(daca exista)
//a diferitelor contexte de framework, etc.
}



.

Edited by Iulius-Foyas, 30 April 2019 - 01:19.


#13
dexterash

dexterash

    --something---

  • Grup: Senior Members
  • Posts: 22,912
  • Înscris: 19.08.2004

View Postelbjorn, on 29 aprilie 2019 - 13:40, said:

Traim intr-o societate in care puterea de concentrare este in continua scadere (multumim apple, hollywood, etc), iar cei care i-ti vor calca pe urme, foarte probabil sa nu poata intelege o logica prea elaborata.
Complet de acord cu tine! Sau nu (prea) ai vrut sa fii un exemplu?

#14
TS030

TS030

    Guru Member

  • Grup: Senior Members
  • Posts: 15,193
  • Înscris: 25.06.2012

View Postjegmihai, on 29 aprilie 2019 - 12:53, said:

Pe scurt, voi sunteți de acord să faceți "muncă multă" în constructorii obiectelor?

Prin "muncă multă" mă refer la operații specifice IO care iau mult timp sau diverse calcule complexe. De asemenea, haideți să presupunem că această muncă este esențială pentru ca obiectul nostru să fie instanțiat corect (și complet) și gata de utilizare.

Eu prefer varianta cu "muncă multă" în constructor pentru a nu fi nevoit mai apoi să apelez alte metode pentru a aduce obiectul într-o stare validă, mi se pare cea mai safe metodă.
Hmm... nu ma pot gandi la situatii in care chiar sa fie esentiala acea "multa munca" in constructor, pentru o instantiere corecta. Rolul unui constructor este de a construi obiectul intr-o stare valida... nu procesari de lunga durata.

#15
Iulius-Foyas

Iulius-Foyas

    Active Member

  • Grup: Members
  • Posts: 1,361
  • Înscris: 21.04.2019
Rolul unui constructor este de a instantia obiectul si atata tot. Daca procesarile sunt de lunga durata sau scurta durata asta decide programatorul in functie de cum foloseste obiectul.

#16
Iulius-Foyas

Iulius-Foyas

    Active Member

  • Grup: Members
  • Posts: 1,361
  • Înscris: 21.04.2019
MyObject mo = new MyObject();
//alt cod facut cu alte obiecte tertze
mo.setData(data); //data => rezultatul operatiilor externe de mai sus
//alt cod facut cu alte obiecte
mo.load(data2); //data2 => rezultatul operatiilor externe de mai sus
//etc
//....
mo.execute().close();


Edited by Iulius-Foyas, 30 April 2019 - 19:34.


#17
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Ce zici de acest cod, fara apelul la setData:

View PostIulius-Foyas, on 30 aprilie 2019 - 19:33, said:

MyObject mo = new MyObject();
//alt cod facut cu alte obiecte
mo.load(data2); //data2 => rezultatul operatiilor externe de mai sus
//etc
//....
mo.execute().close();



functioneaza corect? arunca exceptii? ce se intampla?

Nu spun ca nu e bine ce ai zis, sunt doar curios.

Dar faptul ca trebuie sa apelezi setData (metoda publica) inainte de load (metoda publica), inseamna ca obiectul este intr-un state invalid.


Despre asta vorbeste @jegmihai.

#18
Iulius-Foyas

Iulius-Foyas

    Active Member

  • Grup: Members
  • Posts: 1,361
  • Înscris: 21.04.2019
Stai putin ca fara sa vreau dau nastere la confuzii.Scuze.N-am vrut.

setData(...) si load(...) sunt metode care fac lucruri total diferite.  Nu ma refer la teoria setterilor si getterilor. Uite in loc de setData si load putem sa avem
loadBeveragesData(...) si loadVegetablesData(..)

Exemplu 1:
GroceriesList groceriesList = new GroceriesList();

//citim lista cu bauturi din alt obiect care intoarce
//o structura de tip Bevarages

groceriesList.loadBeveragesData(bevarages);

//citim lista cu legume din alt obiect care intoarce
//o structura de tip Vegetables
groceriesList.loadVegetablesData(vegetables);

groceriesList.process().storeIntoDatabase().close()


Exemplu 2:
//citim lista cu bauturi din alt obiect care intoarce
//o structura de tip Bevarages

//citim lista cu legume din alt obiect care intoarce
//o structura de tip Vegetables

GroceriesList groceriesList = new GroceriesList(new Vegetables(), new Bevarages());
groceriesList.process().storeIntoDatabase().close()


exemplu 3:
//citim lista cu legume din alt obiect care intoarce
//o structura de tip Vegetables
//citim lista cu bauturi din alt obiect care intoarce
//o structura de tip Bevarages
GroceriesList groceriesList = new GroceriesList();
groceriesList.vegetables = vegetables;
groceriesList.beverages = beverages;

groceriesList.process().storeIntoDatabase().close()


Prototype clasa pt exemplul 1 si 2
public GroceriesList() {
private Vegetables vegetables;
private Beverages beverages;

public GroceriesList(){
	 vegetables = new Vegetables();
	 beverages = new Beverages();
}

public GroceriesList(Vegetables vegetables, Beverages beverages){
	 this();
	 this.vegetables = vegetables;
	 this.beverages = beverages);
}

public void loadVegetablesData(Vegetables vegetables){
this.vegetables = vegetables;
}

public void loadBeveragesData(Beverages beverages) {
this.beverages = beverages;
}

public GroceriesList process(){
	 //cod specific
}

public GroceriesList storeIntoDatabase(){
	 //cod specific
}

public GroceriesList close(){
	 //cod specific close DB conn, handles, etc.
}
}

Prototype pt clasa pt exemplu1 1, 2, si 3
public GroceriesList() {
	public Vegetables vegetables;
	public Beverages beverages;

   //restul codului  identic cu prototype de mai sus pt exemplele 1 si 2
}

Ai o clasa care poate o instantia un obiect.Modul cum este folosit acel obiect reprezinta exclusiv sarcina programatorului.
Chestiunea cu "existenta nevalida sau valida" este o chestiune subiectiva, care depinde efectiv de modul de incapsulare a membrilor clasei prin
specificatorii de acces/vizibiliate, respectiv "private/public/protected".

Asa cum se observa uneori trebuie sa ai o instantiere in stare "nevalida" , alteori trebuie sa ai o instantiere in stare "valida", daca este sa socotim faptul ca prin stare valida intelegem
totalitatea operatiilor necesare facute intr-un singur pas astfel incat obiectul instantiat sa nu arunce exceptii la utilizarea efectiva a acestuia.

Edited by Iulius-Foyas, 30 April 2019 - 21:49.


Anunturi

Chirurgia spinală minim invazivă Chirurgia spinală minim invazivă

Chirurgia spinală minim invazivă oferă pacienților oportunitatea unui tratament eficient, permițându-le o recuperare ultra rapidă și nu în ultimul rând minimizând leziunile induse chirurgical.

Echipa noastră utilizează un spectru larg de tehnici minim invazive, din care enumerăm câteva: endoscopia cu variantele ei (transnazală, transtoracică, transmusculară, etc), microscopul operator, abordurile trans tubulare și nu în ultimul rând infiltrațiile la toate nivelurile coloanei vertebrale.

www.neurohope.ro

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate