Table of Contents

Laboratorul – Design Patterns 1

Î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.

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:

Singleton-ul va fi punctul de acces global la datele platformei.

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:

Cerințe de implementare:

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:

Exemplu de utilizare Builder (în JSONReader):

Song song = new Song.Builder()
        .title(title)
        .artists(artists)
        .duration(duration)
        .views(views)
        .releaseDate(releaseDate)
        .ratings(ratings)
        .build();

Exemplu de metodă setter în Builder:

public Builder title(String title) {
    this.title = title;
    return this;
}

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:

Cerințe de implementare:

Hint pentru sortare cu Comparator:

// 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()));

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:

Cerințe de implementare:

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:

Formula de calcul a venitului per utilizator:

Cerințe de implementare:

Exemplu de utilizare Visitor (în Spotify.calculateRevenue):

RevenueVisitor visitor = new RevenueVisitor();
for (User user : users) {
    user.accept(visitor);
}
return visitor.getTotalRevenue();

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: