Differences

This shows you the differences between two versions of the page.

Link to this comparison view

poo-ca-cd:laboratoare:static-final [2021/09/18 21:05]
miruna_maria.fatu [Singleton Pattern]
poo-ca-cd:laboratoare:static-final [2022/10/30 18:50] (current)
teodora.stroe2210 [Exerciții]
Line 249: Line 249:
   * pentru obiecte de tip //Factory// (acest design pattern va fi prezentat în cadrul laboratorului 9).   * pentru obiecte de tip //Factory// (acest design pattern va fi prezentat în cadrul laboratorului 9).
  
-{{ :​poo-ca-cd:​laboratoare:​singleton2.png?​400 |}}+{{ :​poo-ca-cd:​laboratoare:​singleton2.png?​500 |}}
  
 Exemple din API-ul Java: [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​Runtime.html | java.lang.Runtime]],​ [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​awt/​Toolkit.html | java.awt.Toolkit]] Exemple din API-ul Java: [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​Runtime.html | java.lang.Runtime]],​ [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​awt/​Toolkit.html | java.awt.Toolkit]]
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]]).
  
-=== Tutorial debugging în IntelliJ ===+==== Deep copy. Shallow copy ==== 
 + 
 +Pentru început, ne propunem să ne familiarizăm cu noțiunea de copie în Java.  
 + 
 +Noțiunea de //reference copy// implică copierea unei **referințe** care pointeaza către un obiect. 
 +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 |}} 
 + 
 +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 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 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> 
 +public class Person { 
 +    private Name name; 
 +    private Address address; 
 + 
 +    public Person(Person firstPerson) { 
 +         ​this.name = firstPerson.name;​ 
 +         ​this.address = firstPerson.address;​ 
 +    } 
 +
 +</​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. Î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> 
 +public class Person { 
 +    private Name name; 
 +    private Address address; 
 + 
 +    public Person(Person otherPerson) { 
 +         ​this.name ​   =  new Name(otherPerson.name);​ 
 +         ​this.address =  new Address(otherPerson.address);​ 
 +    } 
 +
 +</​code>​ 
 + 
 +==== Tutorial debugging în IntelliJ ​====
  
 Luând în considerare următorul scenariu: Luând în considerare următorul scenariu:
Line 385: Line 426:
   * Watch expression - în caseta de Variables apoi + se poate inițializa o variabilă nouă sau una deja existentă care să fie urmărită pe parcursul sesiunii de debug   * Watch expression - în caseta de Variables apoi + se poate inițializa o variabilă nouă sau una deja existentă care să fie urmărită pe parcursul sesiunii de debug
   * Set Value - putem modifica comportamentul programului fară să schimbăm codul sursă, pentru orice variabilă din caseta de Variables click dreapta -> Set Value și putem observa cum se modifică programul cu noua valoare dată   * Set Value - putem modifica comportamentul programului fară să schimbăm codul sursă, pentru orice variabilă din caseta de Variables click dreapta -> Set Value și putem observa cum se modifică programul cu noua valoare dată
 +
 +==== Utilizarea clasei HashMap. Exemple ====
 +Clasa HashMap este un dicționar (tabelă de dispersie / hashtable), o colecție de perechi cheie-valoare unde avem o mapare între cheia unică în colecție și valoarea asociată acesteia, iar această clasă poate fi găsită în pachetul java.util. Principalele metode ale acestei clase sunt:
 +  * ''​put(K key, V value)''​ - adaugă o pereche cheie-valoare sau înlocuiește valoarea asociată unei chei deja existente în HashMap.
 +  * ''​get(Object key)''​ - accesează valoarea asociată unei chei din HashMap.
 +  * ''​size()''​ - returnează numărul de elemente din HashMap.
 +  * ''​containsKey(Object key)''​ - verifică dacă cheia există în HashMap.
 +  * ''​remove(Object key)''​ - șterge o pereche cu cheia respectivă din HashMap.
 +  * ''​clear()''​ - șterge toate elementele din HashMap.
 +
 +Pentru a putea parcurge elementele unui HashMap se poate folosi for-each. Un exemplu de utilizare a metodelor clasei HashMap și de parcurgere a elementelor stocate de această clasă este următorul:
 +<code java5>
 +import java.util.HashMap;​
 +import java.util.Map;​
 +
 +public class Main {
 +    public static void main(String[] args) {
 +        HashMap<​String,​ Integer> grades = new HashMap<>​();​
 +        grades.put("​Celentano",​ 5);
 +        grades.put("​Firicel",​ 8);
 +        grades.put("​Brinzoi",​ 9);
 +        grades.put("​Bobita",​ 10);
 +
 +        System.out.println("​Firicel'​s grade: "+ grades.get("​Firicel"​));​
 +
 +        grades.put("​Firicel",​ 10);
 +        System.out.println("​Firicel'​s grade: "+ grades.get("​Firicel"​));​
 +
 +        for (Map.Entry<​String,​ Integer> entry: grades.entrySet()) {
 +            System.out.println(entry.getKey() + ": " + entry.getValue());​
 +        }
 +    }
 +}
 +</​code>​
 +
 +
  
 ==== Exerciții ==== ==== Exerciții ====
-  - (**3p**) Să se implementeze o clasă ​''​PasswordMaker'' ​ce generează, folosind ''​RandomStringGenerator'', ​parolă pornind ​de la datele unei persoane. Această clasă ​o să conțină următoarele:​  +  - **(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). 
-    * constantă MAGIC_NUMBER având orice valoare doriți  +  - 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ționariar fiecare profesor are 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. 
-    * un String constant MAGIC_STRING,​ lung de minim 20 de caractere, generat random +      - **(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 listă de studenți. Faceți aceste liste de tip final. 
-    un constructor care primește: un String numit ''​name''​ +      ​- ​**(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:​ 
-    ​o metodă ''​getPassword()'' ​care va returna parola  +          - metoda ''​averageGrade''​care calculează media generală a studentului (media tuturor materiile pe care acesta le are). 
-      * parola se construiește concatenând ​următoarele ​șiruri+          - copy constructor-ul clasei 
-        * un șir random de lungime MAGIC_NUMBERgenerat cu ''​RandomStringGenerator''​ și cu un alfabet obținut din 10 caractere obținute random din MAGIC_STRING +          - metoda ​''​getGradeForSubject''​, care primește ca parametru de intrare numele unei materii ​și întoarce nota studentului ​la materia respectivă. 
-        * și șirul format prin conversia ​la String a lungimii lui name + un număr întreg generat random din intervalul [0, 100] +      ​- ​**(1 punct)** Clasa ''​Teacher''​ are trei câmpuri: nume, prenume ​și lista materiilor pe care ei le predau. În această clasa implementați copy constructor
-    Pentru subșiruri ​și alte metode utile consultați documentația clasei [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​String.html | String]] +      - **(2 puncte)** În clasa ''​Database''​ implementați următoarele metode: 
-  (**3p**) Modificați implementarea clasei PasswordMaker astfel încât să respecte conceptul ​de **Singleton pattern** (să permită instanțierea unui singur obiect) +          - ''​findAllStudents''​ - întoarce lista de studenți 
-        * Pornind ​de la exemplul de Singleton din textul laboratorului implementațo versiune ​care urmează principiul de Eager Initialization (singura instanță a clasei este creată la pornirea aplicației,​ indiferent dacă este necesar sau nu) +          - ''​findAllTeachers''​ - întoarce lista de profesori 
-        * Implementațo versiune de Singleton în care variabila ​''​instance'' ​este inițializată într-un bloc static +          - ''​getStudentsBySubject''​ - primește ca parametru numele unei materii șîntoarce lista cu studenții ​care au materia respectivă 
-        * Adăugați un contor care să numere ​de câte ori a fost accesată metoda ​''​getInstance()''​. E nevoie ​ca acest contor să fie static? +          - ''​findTeachersBySubject''​ - primește ca parametru numele unei materii șîntoarce lista cu profesorii ​care predau materia respectivă. 
-        * //Temă de gândire:// Ce se va întâmplă dacă folosim conceptul de Singleton pattern într-un program paralelizatcare rulează pe mai multe linii de execuție (thread-uri). Ce probleme ar putea să apară? +          - ''​getStudentsByAverageGrade'' ​- întoarce lista cu studenții sortați crescător în funcție ​de media lor generală 
-  (**3p**) Să se implementeze o clasă ''​MyImmutableArray'' ​care să conțină+          - ''​getStudentsByGradeForSubject'' ​- primește ​ca parametru numele unei materii și întoarce lista cu studenții care au materia respectivă, sortați după nota pe care au ei la materia respectivă în ordinea crescătoare. 
-    * un field ''​ArrayList<​Integer>​ immutableArray;​'' ​neinițializat în primă fază +       **(1 punct)** În clasa ''​Teacher''​ implementați următoarele metode, care vor apela metodele corespunzătoare din clasa ''​Database'':​ 
-    * un constructor care primește un ArrayList<​Integer>​ și copiază toate elementele din acel array în ''​immutableArray''​ +          ​- ​''​getAllTeachers''​ 
-    o metodă getArray implementată în așa fel încât field-ul ​''​immutableArray''​ să rămână immutable (Hint: ​[[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Collections.html#​unmodifiableList-java.util.List- ​| Collections.unmodifiableList()]]) +          ​- ​''​getTeachersBySubject''​ 
-  (**1p**) Testați clasa ''​MyImmutableArray'' ​demonstrând faptul că instanțele acestei clase sunt imutabile +          - ''​getAllStudents''​ 
-==== Resurse ==== +          - ''​getStudentsBySubject''​ 
-  * {{:poo-ca-cd:​laboratoare:​static-final-singleton:schelet_lab4.zip|Arhiva zip cu clasa RandomStringGenerator.java}}+          - ''​getStudentsByAverageGrade''​ 
 +          - ''​getStudentsByGradeForSubject''​ 
 +      - **(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''​ 
 +          - ''​getTeachersBySubject''​ 
 +          - ''​getAllStudents''​ 
 +          - ''​getStudentsBySubject''​ 
 +          - ''​getStudentsByAverageGrade''​ 
 +          - ''​getStudentsByGradeForSubject''​ 
 +      ​- **(1 punct)** În clasa ''​Database'',​ adăugați un contor drept câmp al clasei, de tip static, care va număra instanțierile clasei în cadrul metodei ​''​getDatabase''​, unde se face instanțierea clasei. Implementați metoda ''​getNumberOfInstances()''​ din ''​Database'',​ care întoarce numărul de instanțieri.    ​ 
 + 
 +<note tip> 
 +Pentru sortarea unui ArrayList (despre care am discutat în cadrul [[poo-ca-cd:​laboratoare:​agregare-mostenire|laboratorului trecut]], ​ puteți folosi metoda sort() din cadrul clasei ArrayList: 
 +<code java> 
 +ArrayList<​String>​ animals = new ArrayList<>​();​ 
 +animals.add("​Dog"​);​ 
 +animals.add("​Cat"​);​ 
 +animals.add("​Sheep"​);​ 
 + 
 +animals.sort(new Comparator<​String>​() { 
 +    @Override 
 +        public int compare(String o1, String o2) { 
 +            return o1.compareTo(o2);​ 
 +        ​} 
 +}); 
 +</​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>​
  
poo-ca-cd/laboratoare/static-final.1631988339.txt.gz · Last modified: 2021/09/18 21:05 by miruna_maria.fatu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0