This shows you the differences between two versions of the page.
poo-ca-cd:laboratoare:static-final [2021/09/21 02:16] miruna_maria.fatu [Singleton Pattern] |
poo-ca-cd:laboratoare:static-final [2022/10/30 18:50] (current) teodora.stroe2210 [Exerciții] |
||
---|---|---|---|
Line 338: | Line 338: | ||
O clasă de tip Singleton poate fi extinsă, iar metodele ei suprascrise, însă într-o clasă cu metode statice acestea nu pot fi suprascrise (//overriden//) (o discuție pe aceasta temă puteți găsi [[http://geekexplains.blogspot.ro/2008/06/can-you-override-static-methods-in-java.html | aici]], și o comparație între static și dynamic binding [[http://geekexplains.blogspot.ro/2008/06/dynamic-binding-vs-static-binding-in.html | aici]]). | O clasă de tip Singleton poate fi extinsă, iar metodele ei suprascrise, însă într-o clasă cu metode statice acestea nu pot fi suprascrise (//overriden//) (o discuție pe aceasta temă puteți găsi [[http://geekexplains.blogspot.ro/2008/06/can-you-override-static-methods-in-java.html | aici]], și o comparație între static și dynamic binding [[http://geekexplains.blogspot.ro/2008/06/dynamic-binding-vs-static-binding-in.html | aici]]). | ||
- | === Deep copy. Shallow copy === | + | ==== Deep copy. Shallow copy ==== |
- | Pentru inceput, ne propunem sa ne familiarizam cu notiunea de copie in Java. | + | Pentru început, ne propunem să ne familiarizăm cu noțiunea de copie în Java. |
- | Notiunea de //reference copy// implica copierea unei **referinte** care pointeaza catre un obiect. | + | Noțiunea de //reference copy// implică copierea unei **referințe** care pointeaza către un obiect. |
- | Exemplu: Daca avem un obiect de tipul Car, iar variabila myCar pointeaza catre acesta, prin crearea unei copii de referinta vom obtine doua variabile myCar ce pointeaza catre acelasi obiect de tipul Car. | + | Exemplu: Dacă avem un obiect de tipul Car, iar variabila myCar pointeaza către acesta, prin crearea unei copii de referință vom obține două variabile myCar ce pointeaza către același obiect de tipul Car. |
+ | {{ :poo-ca-cd:laboratoare:shallow.jpg?300 |}} | ||
- | Notiunea de //object copy// creează insa o copie a obiectului în sine. Deci, dacă am copia din nou obiectul Car, am crea o copie a obiectului în sine, precum și o a doua variabilă de referință ce face referire la acel obiect copiat. | + | Noțiunea de //object copy// creează însă o copie a obiectului în sine. Deci, dacă am copia din nou obiectul Car, am crea o copie a obiectului în sine, precum și o a doua variabilă de referință ce face referire la acel obiect copiat. |
+ | {{ :poo-ca-cd:laboratoare:deep.jpg?300 |}} | ||
- | **//Shallow copy//** se refera la copierea obiectului „principal”, dar nu copiază obiectele "interioare", acestea fiind "impartasite" doar de obiectul original și copia acestuia. De exemplu, daca pentru un obiect de tip Person, am crea un al doilea obiect Person, ambele obiecte ar avea aceleași obiecte Name și Address intrucat schimbarea unuia dintre acestea implica modificarea sa peste tot unde se regaseste referinta obiectului modificat. | + | **//Shallow copy//** se referă la copierea obiectului „principal”, dar nu copiază obiectele "interioare", acestea fiind "împărtășite" doar de obiectul original și copia acestuia. De exemplu, dacă pentru un obiect de tip Person, am crea un al doilea obiect Person, ambele obiecte ar avea aceleași obiecte Name și Address întrucât schimbarea unuia dintre acestea implică modificarea peste tot unde se regăsește referința obiectului modificat. |
- | Putem spune astfel ca cele doua obiecte Person nu sunt independente - daca este modificat obiectul Name al unui obiect Person, schimbarea se va reflecta si in celalat obiect de acest tip. | + | Putem spune astfel că cele două obiecte Person nu sunt independente - dacă este modificat obiectul Name al unui obiect Person, schimbarea se va reflecta și în celălat obiect de acest tip. |
<code java> | <code java> | ||
Line 363: | Line 365: | ||
</code> | </code> | ||
- | Spre deosebire de shallow copy, **//deep copy//** este o copie complet independentă a unui obiect. Dacă am copia obiectul Person, am copia întreaga structură a obiectului. In acest caz, o modificare a obiectului Adress nu ar fi reflectată în cealaltă obiect. Dacă aruncăm o privire asupra codului din exemplul urmator, puteți vedea că nu este folosit doar un //copy constructor// pentru obiectul Person, dar și //copy constructors// pentru obiectele interioare. | + | Spre deosebire de shallow copy, **//deep copy//** este o copie complet independentă a unui obiect. Dacă am copia obiectul Person, am copia întreaga structură a obiectului. În acest caz, o modificare a obiectului Adress nu va fi reflectată în cealalt obiect. Dacă aruncăm o privire asupra codului din exemplul următor, se observă că nu este folosit doar un //copy constructor// pentru obiectul Person, dar și //copy constructors// pentru obiectele interioare. |
<code java> | <code java> | ||
Line 462: | Line 464: | ||
==== Exerciții ==== | ==== Exerciții ==== | ||
- | - **(1 punct)** Folosind de pașii și de debugger, reparați codul din pachetul ''vault'' din cadrul scheletului laboratorului (același care este prezentat în cadrul tutorialului de debug). | + | - **(0 puncte)** Folosind pașii de mai sus și debugger-ul, reparați codul din pachetul ''vault'' din cadrul [[https://github.com/oop-pub/oop-labs/tree/master/src/lab4 | scheletului laboratorului]] (același care este prezentat în cadrul tutorialului de debug). |
- Aveți de implementat o mini aplicație de tip queries dintr-o bază de date cu studenți și cu profesori. Fiecare student are o colecție de asocieri dintre materiile sale și notele la materiile respective de tip dicționar, iar fiecare profesor are o listă de materii pe care le predă. Studenții pot executa operații care sunt doar read-only (acestea nu pot avea efecte de tip write în baza de date - hint: imutabilitate) și profesorii pot executa operații de tip read-write. | - Aveți de implementat o mini aplicație de tip queries dintr-o bază de date cu studenți și cu profesori. Fiecare student are o colecție de asocieri dintre materiile sale și notele la materiile respective de tip dicționar, iar fiecare profesor are o listă de materii pe care le predă. Studenții pot executa operații care sunt doar read-only (acestea nu pot avea efecte de tip write în baza de date - hint: imutabilitate) și profesorii pot executa operații de tip read-write. | ||
- | - **(1 punct)** Având la bază scheletul de cod, faceți clasa Database, care se ocupă cu gestionarea bazei de date a studenților și a profesorilor, o clasă de tip Singleton (tipul de Singleton este la alegerea voastră). Această clasă va conține o listă de profesori și o listă de studenți. Faceți aceste liste de tip final. | + | - **(2 puncte)** Având la bază scheletul de cod, faceți clasa Database, care se ocupă cu gestionarea bazei de date a studenților și a profesorilor, o clasă de tip Singleton cu implementare de tip lazy. Această clasă va conține o listă de profesori și o listă de studenți. Faceți aceste liste de tip final. |
- **(1 punct)** Clasa ''Student'' are trei câmpuri: nume, prenume și un dicționar unde sunt stocate materiile unui student, fiecare materie fiind asociată cu nota studentului la materia respectivă. În această clasă, implementați următoarele: | - **(1 punct)** Clasa ''Student'' are trei câmpuri: nume, prenume și un dicționar unde sunt stocate materiile unui student, fiecare materie fiind asociată cu nota studentului la materia respectivă. În această clasă, implementați următoarele: | ||
- metoda ''averageGrade'', care calculează media generală a studentului (media tuturor materiile pe care acesta le are). | - metoda ''averageGrade'', care calculează media generală a studentului (media tuturor materiile pe care acesta le are). | ||
Line 484: | Line 486: | ||
- ''getStudentsByAverageGrade'' | - ''getStudentsByAverageGrade'' | ||
- ''getStudentsByGradeForSubject'' | - ''getStudentsByGradeForSubject'' | ||
- | - **(1 punct)** În clasa Student implementați următoarele metode, care vor apela metodele corespunzătoare din clasa ''Database'' (atenție, aici metodele trebuie să întoarcă rezultate imutabile, sub forma de deep copy, folosind modalitatea prezentată în laborator, folosind [[https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html | Collections.unmodifiableList()]] pentru ca evita posibilitatea de a modifica rezultatele, care sunt read-only): | + | - **(2 puncte)** În clasa Student implementați următoarele metode, care vor apela metodele corespunzătoare din clasa ''Database'' (atenție, aici metodele trebuie să întoarcă rezultate imutabile, sub forma de deep copy, folosind modalitatea prezentată în laborator, folosind [[https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html | Collections.unmodifiableList()]] pentru ca evita posibilitatea de a modifica rezultatele, care sunt read-only): |
- ''getAllTeachers'' | - ''getAllTeachers'' | ||
- ''getTeachersBySubject'' | - ''getTeachersBySubject'' | ||
Line 508: | Line 510: | ||
}); | }); | ||
</code> | </code> | ||
+ | </note> | ||
+ | |||
+ | <note tip> | ||
+ | Pentru shallow copy și deep copy la ArrayList avem în felul următor: | ||
+ | * shallow copy: | ||
+ | <code java> | ||
+ | List<Student> shallowCopy = new ArrayList<>(list); | ||
+ | </code> | ||
+ | * deep copy: | ||
+ | <code java> | ||
+ | List<Student> deepCopy = new ArrayList<>(); | ||
+ | for (var student: list) { | ||
+ | // folosind constructor cu deep copy | ||
+ | deepCopy.add(new Student(student)); | ||
+ | } | ||
+ | return deepCopy; | ||
+ | </code> | ||
</note> | </note> | ||