Laborator 4
I. Cuplaj
- consideram urmatorul program:
class C1{ int i1,i2,a; void f1(){ i1=f2(a); } int f2(int a){ return a+a; } int f3(int a1, int a2){ i2=f2(a1)+f2(a2); f1(); i2=i1; return a1+a2+i1; } } class C2{ int i1, i2; C1 f1(boolean a){ C1 c=new C1; c.i1=c.i2=1; i1=a?c.f2(i1):c.f3(i1,i2); return c; } C2 f2(int a){ C1 c=f1(a<0); c.i1=i1; c.i2=i2; c.f3(a,-a); return this; } }
- daca realizam diagrama de apeluri si de dependente de date pentru C1 si C2 obinem:

- cu nume_clasa.nume_membru s-a notat faptul ca este voba de membrul apartinand acelei clase sau a unei instante a acelei clase si nu faptul ca membrul este static
- cu linie continua s-a notat faptul ca o metoda apeleaza alta metoda (dependenta functionala)
- cu linie punctata s-a notat faptul ca o functie are nevoie de anumite variabile externe ei (dependenta de date)
- se poate remarca faptul ca unele dependente prin tranzitivitate, urmand un drum in graful orientat al dependentelor, pot sa duca la alte dependente, de exemplu:
C2.f2 depinde de C2.f3 si C1.f3 depinde de C1.f1 => C2.f2 depinde indirect de C1.f1
- faptul ca mai multe functii depind si modifica aceleasi date face ca folosirea acestor functii sa fie foarte problematica, din cauza ca ele modifica starea contextului (clasa), si aceasta modificare nu este imediat vizibila doar din semnatura functiei, ci apare ca efect colateral ("side effect"), de exemplu:
C1.f1 modifica pe C1.i1 si il foloseste pe C1.i2, iar C1.f3 il modifica pe C1.i2 si il foloseste pe C1.i1 si deci conteaza ordinea in care apelam C1.f1 si C1.f3 pentru a seta corect atributele C1.i1 si C1.i2
- acest mod de programare instituie un cuplaj strans atat intre clasele C1 si C2 cat si intre metodele aceleiasi clase
- in aceasta situatie este foarte greu sa modificam o anumita metoda sau un anumit tip de date, fiindca aproape inevitabil, modificarea va afecta multe alte locuri din program, fara ca aceasta sa fie intentia noastra, si de multe ori chiar fara sa ne dam seama. Totodata cuplajul strans are tendinta sa reflecte toate folosirile unor metode sau atribute in multe alte locuri, cu rezultate de cele mai multe ori imprevizibile si in acelasi timp greu de urmarit catre sau la originea lor
- o alta situatie in care apare cuplajul strans este atunci cand avem clase cu foarte multi membri in interfata lor. In aceasta situatie aproape inevitabil fiecare membru al acelei clase va depinde de mai multi membri
- de multe ori chiar adaugarea de noi functionalitati la un cod in care apare cuplajul strans este foarte grea, pe de-o parte din cauza ca ceea ce exista deja este de cele mai multe ori proiectat intr-un mod foarte particularizat in contextul vechiului program, iar pe de alta parte din cauza ca noile adaugiri sau modificari vor aduce de multe ori noi interactiuni (dependente) care ulterior prin tranzitivitate se vor reflecta in multe alte parti
II Legea lui Demeter (LoD)
- LoD sugereaza anumite reguli pe care daca le respectam, codul rezultat va avea un cuplaj mai slab. Ea se adauga regulilor enumerate anterior si se prezinta in doua forme:
# this si super # atributele clasei C # parametrii metodei M # obiectele create in interiorul lui M prin apelarea constructorului sau prin apelul unei metode care creaza obiectul # variabile globale
class Point{ double x,y; Point(double x,double y){ this.x=x; // ok (din regulile LoD 2, 3) this.y=y;// ok (2, 3) } double mod(){...} double getX(){...} double setX(double x){...} } class Line{ Point p1,p2; Line(){ p1=new Point(0,0); // ok (2, 4) p2=new Point(0,0); // ok (2, 4) } double len(){...} } ... Line l=new Line(); // ok (4) show(l.p1.x); //NU, accesare atribut al instantei unei alte clase show(l.getP1().x); //NU, accesare atribut al instantei unei alte clase show(l.getP1().getX() ); //ok (accesare metode de interfata)
III. Teme
1. Sa se conceapa un algoritm de sortare care sa sorteze obiecte cat mai diverse, grupate in array-uri ([ ]), folosind o functie de forma
Sortare s= new Sortare(); s.sorteaza(a,”nume”);
In acest caz functia sorteaza va sorta obiectele din a dupa atributul lor “nume”. Se vor folosi doar elementele expuse pena acum la laborator si nu alte abilitati ale limbajului Java gen “Reflection”. Se va testa functionarea clasei Sortare pe minim doua clase diferite care sa formeze obiectele de sortat.
2. Sa se conceapa o clasa “Colectie” care folosind array-uri ([ ]), sa implementeze o colectie care poate sa contina oricate elemente. Elementele vor trebui sa implementeze o functie care nu primeste niciun argument si care returneaza true daca obiectul mai este necesar. Nu este important motivul pentru care un obiect nu mai este necesar. Clasa “Colectie” va implementa trei metode:
Programul de test va folosi colectii formate din cel putin instante a doua clase distincte si va testa toate cele trei metode cerute