This shows you the differences between two versions of the page.
|
poo-ca-cd:laboratoare:design-patterns-part-two [2025/12/03 02:35] florian_luis.micu [Dezavantaje] |
poo-ca-cd:laboratoare:design-patterns-part-two [2025/12/03 02:54] (current) florian_luis.micu [Exemplu complet varianta simplă] |
||
|---|---|---|---|
| Line 20: | Line 20: | ||
| - | ======Builder====== | + | ======👷 Builder====== |
| **Builder** este un **creational design pattern** folosit când ai obiecte complexe, cu **multe câmpuri opționale** sau **pași de inițializare diferiți**. El separă construcția obiectului de reprezentarea lui, astfel încât același proces de construire poate genera obiecte diferite. | **Builder** este un **creational design pattern** folosit când ai obiecte complexe, cu **multe câmpuri opționale** sau **pași de inițializare diferiți**. El separă construcția obiectului de reprezentarea lui, astfel încât același proces de construire poate genera obiecte diferite. | ||
| Line 293: | Line 293: | ||
| =====Exemplu complet varianta simplă===== | =====Exemplu complet varianta simplă===== | ||
| - | Există o variantă mai simplă a acestui pattern care folosește o clasă internă și pe care o veți folosi mai des în proiectele voastre: | + | Există o variantă **mai simplă** a acestui pattern care folosește o clasă internă și pe care o veți folosi mai des în proiectele voastre: |
| <code java> | <code java> | ||
| Line 365: | Line 365: | ||
| <note tip> | <note tip> | ||
| - | Este **mult mai ușor să scrieți** și, mai important, **să citiți** acest cod. La fel ca în cazul constructorului, putem verifica parametrii trecuți pentru orice încălcare, cel mai adesea în cadrul metodei ''build()'' sau a metodei setter, și putem arunca ''IllegalStateException'' dacă există încălcări înainte de a crea o instanță a clasei. | + | * Este **mult mai ușor să scrieți** și, mai important, **să citiți** acest cod. La fel ca în cazul constructorului, putem verifica parametrii trecuți pentru orice încălcare, cel mai adesea în cadrul metodei ''build()'' sau a metodei setter, și putem arunca ''IllegalStateException'' dacă există încălcări înainte de a crea o instanță a clasei. |
| + | * Vă încurajăm să **folosiți această versiune a pattern-ului Builder** și să recurgeți la varianta mai complexă doar dacă aveți nevoie de mai mulți Builderi specifici. | ||
| </note> | </note> | ||
| Line 389: | Line 390: | ||
| </code> | </code> | ||
| </note> | </note> | ||
| - | ======Observer====== | + | ======👀 Observer====== |
| - | Observer este un design pattern comportamental folosit atunci când ai un obiect (denumit Subject) care trebuie să notifice automat alte obiecte (Observeri) atunci când starea sa internă se schimbă, practic definând o relație 1 la n. | + | Observer este un **behavioral design pattern** folosit atunci când ai un obiect (denumit Subject) care trebuie să **notifice** automat alte obiecte (Observeri) atunci când starea sa internă se schimbă, practic definând o relație **1:N**. |
| - | Este extrem de util când vrei decuplare, adică Subjectul să nu depindă de logica observatorilor. | + | Este extrem de util când vrei decuplare, adică subiectul să nu depindă de logica observatorilor. |
| =====Problema reală pe care o rezolvă Observer===== | =====Problema reală pe care o rezolvă Observer===== | ||
| Line 444: | Line 445: | ||
| Observer rezolvă asta printr-un principiu simplu: | Observer rezolvă asta printr-un principiu simplu: | ||
| - | Subjectul nu mai știe cine îl observă. Doar păstrează o listă de observatori și îi notifică generic. | + | **Subiectul nu mai știe cine îl observă. Doar păstrează o listă de observatori și îi notifică generic.** |
| =====Structura pattern-ului===== | =====Structura pattern-ului===== | ||
| Observer are 4 componente principale: | Observer are 4 componente principale: | ||
| - | * Subject – menține o listă de observatori și le trimite notificări. | + | * **Subject** – menține o listă de observatori și le trimite notificări. |
| - | * Observer (Interfața pentru observatori) – definește metoda update. | + | * **Observer** (Interfața pentru observatori) – definește metoda update. |
| - | * ConcreteSubject – Subject real care reține starea ce se schimbă. | + | * **ConcreteSubject** – Subject real care reține starea ce se schimbă. |
| - | * ConcreteObservers – obiecte care reacționează la schimbări. | + | * **ConcreteObservers** – obiecte care reacționează la schimbări. |
| Această structură decuplează complet obiectele între ele: subiectul nu știe cine îl ascultă, știe doar că trebuie să notifice. | Această structură decuplează complet obiectele între ele: subiectul nu știe cine îl ascultă, știe doar că trebuie să notifice. | ||
| Line 580: | Line 580: | ||
| <note tip> | <note tip> | ||
| - | * În proiecte mari, în loc să faceți voi lista de observatori manual, se folosesc librării precum Guava EventBus, Akka Event Stream, sau Spring ApplicationEvents. | + | * În proiecte mari, în loc să faceți voi lista de observatori manual, se folosesc librării precum **Guava EventBus**, **Akka Event Stream**, sau **Spring ApplicationEvents**. |
| - | * În locul listei simple de observatori, în proiecte moderne se folosesc API-uri reactive: java.util.concurrent.Flow sau RxJava / Project Reactor, care permit backpressure și stream-uri de evenimente mai complexe. | + | * În locul listei simple de observatori, în proiecte moderne se folosesc **API-uri reactive**: **java.util.concurrent.Flow** sau **RxJava** / **Project Reactor**, care permit **backpressure** și **stream-uri de evenimente mai complexe**. |
| </note> | </note> | ||
| - | ======Strategy====== | + | ======🎲 Strategy====== |
| - | Strategy este un comportamental design pattern care permite definirea unei familii de algoritmi, fiind încapsulați și interschimbabili. Strategy permite schimbarea comportamentului unui obiect în timpul execuției fără a modifica codul clientului care îl folosește. | + | Strategy este un **behavioral design pattern** care permite definirea unei **familii de algoritmi**, fiind **încapsulați** și **interschimbabili**. Strategy permite schimbarea comportamentului unui obiect în timpul execuției fără a modifica codul clientului care îl folosește. |
| =====Problema reală pe care o rezolvă Strategy===== | =====Problema reală pe care o rezolvă Strategy===== | ||
| Line 629: | Line 629: | ||
| Structura Strategy se bazează pe 3 elemente principale: | Structura Strategy se bazează pe 3 elemente principale: | ||
| - | * Interfața Strategy, care definește metoda comună pentru algoritmi. | + | * **Interfața Strategy**, care definește metoda comună pentru algoritmi. |
| - | * Strategiile concrete, care implementează algoritmul specific. | + | * **Strategiile concrete**, care implementează algoritmul specific. |
| - | * Contextul, care folosește o strategie și poate să o schimbe la runtime. | + | * **Contextul**, care folosește o strategie și poate să o schimbe la runtime. |
| Această structură permite adăugarea de noi algoritmi fără a modifica codul contextului, respectând principiul Open/Closed. | Această structură permite adăugarea de noi algoritmi fără a modifica codul contextului, respectând principiul Open/Closed. | ||
| Line 755: | Line 755: | ||
| <note tip> | <note tip> | ||
| - | În aplicații Spring sau Quarkus, Strategy este folosit în bean-uri, pentru a schimba comportamentul fără a modifica clientul. | + | În aplicații **Spring** sau **Quarkus**, Strategy este folosit în **bean-uri**, pentru a schimba comportamentul fără a modifica clientul. |
| </note> | </note> | ||
| - | ======Command====== | + | ======🎮 Command====== |
| - | Command este un comportamental design pattern folosit pentru a încapsula o solicitare sau o acțiune ca un obiect. Acest pattern permite parametrizarea obiectelor cu diferite acțiuni, stocarea cererilor și posibilitatea de a le executa mai târziu, inclusiv să le anulezi sau să le refaci. | + | Command este un **behavioral design pattern** folosit pentru a **încapsula o solicitare** sau o **acțiune** ca un obiect. Acest pattern permite **parametrizarea** obiectelor cu diferite acțiuni, **stocarea** cererilor și **posibilitatea de a le executa mai târziu**, inclusiv să le **anulezi** sau să le **refaci**. |
| =====Problema reală pe care o rezolvă Command===== | =====Problema reală pe care o rezolvă Command===== | ||
| Line 783: | Line 783: | ||
| * Gestionarea undo/redo devine complicată – fiecare metodă are propria logică de inversare, iar clientul trebuie să cunoască starea internă a editorului pentru a implementa undo/redo corect. | * Gestionarea undo/redo devine complicată – fiecare metodă are propria logică de inversare, iar clientul trebuie să cunoască starea internă a editorului pentru a implementa undo/redo corect. | ||
| - | Command pattern încapsulează fiecare acțiune ca un obiect separat. Fiecare comandă are metode precum execute() și undo(), astfel încât: | + | Command pattern încapsulează fiecare acțiune ca un obiect separat. Fiecare comandă are metode precum ''execute()'' și ''undo()'', astfel încât: |
| * Clientul (UI-ul editorului) nu știe ce face comanda, doar o execută. | * Clientul (UI-ul editorului) nu știe ce face comanda, doar o execută. | ||
| * Adăugarea unei noi acțiuni nu implică modificarea codului clientului, trebuie doar să creăm o nouă comandă. | * Adăugarea unei noi acțiuni nu implică modificarea codului clientului, trebuie doar să creăm o nouă comandă. | ||
| Line 791: | Line 791: | ||
| Structura se bazează pe 4 elemente principale: | Structura se bazează pe 4 elemente principale: | ||
| - | * Command-ul (interfața sau clasa abstractă) definește metoda execute(). | + | * **Command-ul** (interfața sau clasa abstractă) definește metoda execute(). |
| - | * Command-urile concrete implementează această interfață și definesc acțiuni specifice. | + | * **Command-urile concrete** implementează această interfață și definesc acțiuni specifice. |
| - | * Invoker-ul, care apelează comanda fără să știe ce face efectiv. | + | * **Invoker-ul**, care apelează comanda fără să știe ce face efectiv. |
| - | * Receiver-ul, obiectul care efectuează acțiunea reală. | + | * **Receiver-ul**, obiectul care efectuează acțiunea reală. |
| Această structură permite stocarea, execuția și inversarea acțiunilor fără a expune detaliile interne ale obiectelor implicate. | Această structură permite stocarea, execuția și inversarea acțiunilor fără a expune detaliile interne ale obiectelor implicate. | ||
| Line 986: | Line 986: | ||
| <note tip> | <note tip> | ||
| - | Pattern-ul Command este foarte folosit în aplicații enterprise moderne cu RabbitMQ, Kafka sau task queues, unde „comanda” devine un mesaj. | + | Pattern-ul Command este foarte folosit în aplicații enterprise moderne cu **RabbitMQ**, **Kafka** sau **task queues**, unde „comanda” devine un mesaj. |
| </note> | </note> | ||
| - | ======Tips & Tricks Design Patterns====== | + | ======🪄 Tips & Tricks Design Patterns====== |
| =====Comparare între Design Patterns===== | =====Comparare între Design Patterns===== | ||
| Line 1059: | Line 1059: | ||
| <note tip> | <note tip> | ||
| Putem reduce și mai mult comparația celor 3 pattern-uri astfel: | Putem reduce și mai mult comparația celor 3 pattern-uri astfel: | ||
| - | * Relație 1:N - Strategy - Un obiect (1) poate avea mai multe prețuri (N). | + | * **Relație 1:N** - **Strategy** - Un obiect (1) poate avea mai multe prețuri (N). |
| - | * Relație N:N - Visitor - Mai multe tiprui de noduri (N) pot avea mai mulți algoritmi de exportare (N). | + | * **Relație N:N** - **Visitor** - Mai multe tiprui de noduri (N) pot avea mai mulți algoritmi de exportare (N). |
| - | * Operații care necesită istoric (undo/redo/do) - Command - Pictează o formă (do), apasă CTRL + Z (undo), apasă SHIFT + CTRL + Z (redo). | + | * **Operații care necesită istoric** (undo/redo/do) - **Command** - Pictează o formă (do), apasă CTRL + Z (undo), apasă SHIFT + CTRL + Z (redo). |
| </note> | </note> | ||
| Line 1073: | Line 1073: | ||
| <note important> | <note important> | ||
| - | Deși este recomandat să combinați aceste pattern-uri este foarte important să nu creați un sistem mult prea complex pentru nevoia aplicației voastre. Folosind ideologia //"Sometimes less is more"// vă recomandăm să nu optimizați prematur proiectele voastre și să țineți cont de principiul [[https://codesignal.com/learn/courses/applying-clean-code-principles/lessons/kiss-keep-it-simple-stupid-strategies|KISS]]. | + | Deși este recomandat să combinați aceste pattern-uri este foarte important **să nu creați un sistem mult prea complex** pentru nevoia aplicației voastre. Folosind ideologia //"Sometimes less is more"// vă recomandăm să nu optimizați prematur proiectele voastre și să țineți cont de principiul [[https://codesignal.com/learn/courses/applying-clean-code-principles/lessons/kiss-keep-it-simple-stupid-strategies|KISS]]. |
| </note> | </note> | ||
| <note tip> | <note tip> | ||
| - | Pentru a vedea mai multe Design Patterns și pentru a le compara vă recomandăm să studiați catalogul de pe [[https://refactoring.guru/design-patterns/catalog|Refactoring Guru]]. | + | Pentru a vedea mai multe Design Patterns și pentru a le compara vă recomandăm să **studiați** catalogul de pe [[https://refactoring.guru/design-patterns/catalog|Refactoring Guru]]. |
| </note> | </note> | ||
| Line 1089: | Line 1089: | ||
| <note important> | <note important> | ||
| - | În cadrul acestui laborator, exercițiile valorează în total **18p**. Pentru primirea punctajului maxim pe acest laborator, trebuie să acumulați 10p din rezolvarea exercițiilor, orice depășește 10p fiind contorizat ca și bonus. | + | În cadrul acestui laborator, exercițiile valorează în total **18p**. Pentru primirea punctajului maxim pe acest laborator, **trebuie să acumulați 10p** din rezolvarea exercițiilor, orice depășește 10p **nu va fi contorizat ca bonus**. |
| </note> | </note> | ||