Differences

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

Link to this comparison view

poo:laboratoare:11-backup [2025/12/14 17:19] (current)
george.tudor1906 created
Line 1: Line 1:
 +
 +===== Laboratorul – Design Patterns 1 =====
 +
 +<​hidden>​{{:​poo:​laboratoare:​arhiva_dp1.zip|Arhiva laborator}}</​hidden>​
 +
 +<note important>​
 +
 +În cadrul acestui laborator se va lucra pe baza scheletului pus la dispoziție.
 +
 +Fiecare TODO este numerotat conform problemei ce trebuie rezolvată.
 +
 +În urma realizării cerințelor,​ se va obține o platformă de streaming muzical.
 +</​note>​
 +
 +=== Problema 1 - Singleton ===
 +
 +Se cere implementarea Design Pattern-ului **Singleton** în cadrul clasei **//​Spotify//​**.
 +Clasa **//​Spotify//​** reprezintă componenta principală a aplicației,​ gestionând datele
 +platformei (utilizatori și melodii).
 +
 +Pattern-ul **Singleton** asigură existența unei singure instanțe a clasei pe
 +parcursul execuției programului.
 +
 +Cerințe de implementare:​
 +
 +  * Declarați constructorul clasei ca **PRIVATE**;​
 +  * Adăugați un atribut **STATIC PRIVATE** de tip **Spotify** pentru instanța unică;
 +  * Implementați o metodă **PUBLICĂ STATICĂ** //​getInstance()//​ care:
 +    * creează instanța dacă nu există;
 +    * returnează instanța existentă;
 +  * Instanțiați listele (**users**, **songs**, **observers**) în constructorul privat.
 +
 +<note tip>
 +Singleton-ul va fi punctul de acces global la datele platformei.
 +</​note>​
 +
 +=== Problema 2 - Factory ===
 +
 +Pornind de la clasa abstractă **//​User//​**,​ se va implementa Design Pattern-ul **Factory**
 +prin intermediul claselor **//​Regular//​**,​ **//​Premium//​** și **//​UltraPremium//​** care moștenesc **//​User//​**.
 +
 +Factory pattern centralizează logica de creare a obiectelor, ascunzând detaliile
 +de implementare și permițând extinderea ușoară cu noi tipuri.
 +
 +Valorile pentru câmpul **subscription**:​
 +
 +  * **Regular**:​ 9.99
 +  * **Premium**:​ 14.99
 +  * **UltraPremium**:​ 19.99
 +
 +Cerințe de implementare:​
 +
 +  * Clasele **Regular**,​ **Premium**,​ **UltraPremium** extind **User**;
 +  * Fiecare clasă își setează **subscription** în constructorul propriu;
 +  * **UserFactory** conține metoda statică //​createUser()//​ care primește un **UserType** și returnează instanța corespunzătoare;​
 +  * În **JSONReader**,​ folosiți factory-ul pentru a crea utilizatorii.
 +
 +
 +=== Problema 3 - Builder ===
 +
 +Se cere implementarea Design Pattern-ului **Builder** în cadrul clasei **//​Song//​**.
 +
 +Un cântec conține: **title**, **artists**,​ **duration**,​ **views**, **releaseDate**,​ **ratings**.
 +
 +Builder pattern permite construirea obiectelor complexe pas cu pas, oferind
 +o alternativă la constructorii cu mulți parametri.
 +
 +Cerințe de implementare:​
 +
 +  * Definiți o clasă internă statică **Builder** în **Song**;
 +  * Builder-ul conține câmpuri identice cu cele din **Song**;
 +  * Fiecare metodă setter din Builder returnează //this// (pentru *method chaining*);
 +  * Metoda //build()// creează și returnează obiectul **Song**;
 +  * Constructorul **Song** este **PRIVAT** și primește un **Builder** ca parametru;
 +  * În **JSONReader**,​ folosiți Builder-ul pentru a crea melodiile.
 +
 +Exemplu de utilizare Builder (în **JSONReader**):​
 +
 +<code java>
 +Song song = new Song.Builder()
 +        .title(title)
 +        .artists(artists)
 +        .duration(duration)
 +        .views(views)
 +        .releaseDate(releaseDate)
 +        .ratings(ratings)
 +        .build();
 +</​code>​
 +
 +Exemplu de metodă setter în Builder:
 +
 +<code java>
 +public Builder title(String title) {
 +    this.title = title;
 +    return this;
 +}
 +</​code>​
 +
 +=== Problema 4 - Strategy ===
 +
 +Fiecare utilizator poate alege modul în care sunt afișate cântecele, în funcție
 +de un criteriu de sortare preferat.
 +
 +Strategy pattern permite schimbarea algoritmului de sortare la runtime, fără
 +a modifica codul clientului.
 +
 +Interfața **//​SortingStrategy//​** definește metoda //​sortedSongs(List<​Song>​)//​.
 +
 +Strategii de implementat:​
 +
 +  * **AverageScoreStrategy** - sortare **DESCRESCĂTOARE** după scorul mediu;
 +  * **TotalViewsStrategy** - sortare **DESCRESCĂTOARE** după numărul de views;
 +  * **ReleaseYearStrategy** - sortare **CRESCĂTOARE** după data lansării (*oldest first*).
 +
 +Cerințe de implementare:​
 +
 +  * Implementați cele trei strategii;
 +  * //​User.getSortedSongs()//​ delegă sortarea către strategia setată;
 +  * În **JSONReader**,​ citiți câmpul //"​sortingStrategy"//​ din JSON și setați strategia corespunzătoare (valori: //"​averageScore"//,​ //"​totalViews"//,​ //"​releaseYear"//​).
 +
 +Hint pentru sortare cu Comparator:
 +
 +<code java>
 +// Sortare DESCRESCĂTOARE după un câmp
 +songs.sort((s1,​ s2) -> s2.getField().compareTo(s1.getField()));​
 +
 +// Sortare CRESCĂTOARE după un câmp
 +songs.sort((s1,​ s2) -> s1.getField().compareTo(s2.getField()));​
 +</​code>​
 +
 +
 +=== Problema 5 - Observer ===
 +
 +Utilizatorii platformei pot primi notificări când un cântec nou este adăugat.
 +
 +Observer pattern permite notificarea automată a obiectelor interesate (**observers**)
 +când starea unui obiect (**subject**) se schimbă.
 +
 +Interfețele din schelet:
 +
 +  * **Subject** - definește //​addObserver//,​ //​removeObserver//,​ //​notifyObservers//​
 +  * **Observer** - definește //​update(String message)//
 +
 +Cerințe de implementare:​
 +
 +  * **Spotify** implementează **Subject** și menține lista de observatori;​
 +  * **User** implementează **Observer** și afișează mesajul primit în //​update()//;​
 +  * În //​addSong()//,​ după adăugarea melodiei, notificați observatorii cu mesajul: //"New song added: <​titlu>"//;​
 +  * În //​readData()//,​ după încărcarea utilizatorilor,​ adăugați-i ca observatori.
 +
 +=== Problema 6 - Visitor ===
 +
 +Pentru calculul venitului total lunar, se va folosi Design Pattern-ul **Visitor**.
 +
 +Visitor pattern permite adăugarea de operații noi asupra obiectelor fără a
 +modifica clasele acestora. „Vizitorul” parcurge elementele și aplică operații
 +specifice fiecărui tip.
 +
 +Interfețele din schelet:
 +
 +  * **Element** - definește //​accept(Visitor)//​
 +  * **Visitor** - definește //visit()// pentru fiecare tip de utilizator
 +
 +Formula de calcul a venitului per utilizator:
 +
 +  * //revenue = subscription * (1 - discount/​100.0) * VAT//
 +  * unde //VAT = 1.19//
 +
 +Cerințe de implementare:​
 +
 +  * **User** implementează **Element**;​
 +  * **Regular**,​ **Premium**,​ **UltraPremium** implementează //​accept()//​ apelând //​visitor.visit(this)//;​
 +  * **RevenueVisitor** implementează **Visitor** cu metode //visit()// pentru fiecare tip;
 +  * **RevenueVisitor** acumulează //​totalRevenue//​ și oferă //​getTotalRevenue()//;​
 +  * //​Spotify.calculateRevenue()//​ creează un visitor, parcurge userii și returnează venitul total.
 +
 +Exemplu de utilizare Visitor (în //​Spotify.calculateRevenue//​):​
 +
 +<code java>
 +RevenueVisitor visitor = new RevenueVisitor();​
 +for (User user : users) {
 +    user.accept(visitor);​
 +}
 +return visitor.getTotalRevenue();​
 +</​code>​
 +
 +
 +=== BONUS ===
 +
 +Implementați pattern-ul **Observer** și pentru rating-uri.
 +
 +Când un utilizator adaugă un rating unui cântec, toți utilizatorii care au dat
 +anterior un rating aceluiași cântec vor fi notificați.
 +
 +Cerințe de implementare:​
 +
 +  * **Song** menține o listă de observatori (utilizatorii care au dat rating);
 +  * La //​addRating()//,​ adăugați rating-ul, apoi notificați observatorii existenți cu mesajul: //"New rating for: <​titlu>"//;​
 +  * Utilizatorul care adaugă rating-ul devine și el observator pentru viitor.
  
poo/laboratoare/11-backup.txt · Last modified: 2025/12/14 17:19 by george.tudor1906
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