This shows you the differences between two versions of the page.
poo-ca-cd:laboratoare:design-patterns [2024/11/17 18:53] maria.enescu |
poo-ca-cd:laboratoare:design-patterns [2024/11/20 14:42] (current) bogdan.rusu1707 [Exerciții] |
||
---|---|---|---|
Line 35: | Line 35: | ||
- | În laboratoarele precedente au fost descrise patternurile [[:poo-ca-cd:laboratoare:static-final#singleton_pattern|Singleton]] și [[:poo-ca-cd:laboratoare:visitor|Visitor]]. //Singleton// este un pattern creațional, simplu, a cărui folosire este controversată (vedeți în [[:poo-ca-cd:laboratoare:static-final#singleton_pattern|laborator]] explicația cu anti-pattern). //Visitor// este un pattern comportamental, și după cum ați observat oferă avantaje în anumite situații, în timp ce pentru altele nu este potrivit. Pattern-urile comportamentale modelează interacțiunile dintre clasele și componentele unei aplicații, fiind folosite în cazurile în care vrem sa facem un design mai clar și ușor de adaptat și extins. | + | În laboratoarele precedente au fost descrise patternurile [[https://ocw.cs.pub.ro/courses/poo-ca-cd/laboratoare/constructori-referinte|Singleton]] și [[https://ocw.cs.pub.ro/courses/poo-ca-cd/laboratoare/visitor|Visitor]]. //Singleton// este un pattern creațional, simplu, a cărui folosire este controversată (vedeți în [[:poo-ca-cd:laboratoare:static-final#singleton_pattern|laborator]] explicația cu anti-pattern). //Visitor// este un pattern comportamental, și după cum ați observat oferă avantaje în anumite situații, în timp ce pentru altele nu este potrivit. Pattern-urile comportamentale modelează interacțiunile dintre clasele și componentele unei aplicații, fiind folosite în cazurile în care vrem sa facem un design mai clar și ușor de adaptat și extins. |
Line 187: | Line 187: | ||
* implementează interfața Observator | * implementează interfața Observator | ||
- | Aceasta schemă se poate extinde, în funcție de aplicație, observatorii pot ține referințe catre subiect sau putem adauga clase speciale pentru reprezentarea evenimentelor, notificarilor. Un alt exemplu îl puteți găsi [[http://www.research.ibm.com/designpatterns/example.htm |aici]]. | + | Aceasta schemă se poate extinde, în funcție de aplicație, observatorii pot ține referințe catre subiect sau putem adauga clase speciale pentru reprezentarea evenimentelor, notificarilor. |
=== Implementare === | === Implementare === | ||
- | Tookit-urile GUI, cum este și [[http://en.wikipedia.org/wiki/Swing_%28Java%29|Swing]] folosesc acest design pattern, de exemplu apăsarea unui buton generează un eveniment ce poate fi transmis mai multor //listeners// înregistrați acestuia ([[http://www.programcreek.com/2009/01/the-steps-involved-in-building-a-swing-gui-application/|exemplu]]). | + | Tookit-urile GUI, cum este și [[http://en.wikipedia.org/wiki/Swing_%28Java%29|Swing]] folosesc acest design pattern, de exemplu apăsarea unui buton generează un eveniment ce poate fi transmis mai multor //listeners// înregistrați acestuia. |
API-ul Java oferă clasele [[http://docs.oracle.com/javase/8/docs/api/java/util/Observer.html |Observer]] și [[http://docs.oracle.com/javase/8/docs/api/java/util/Observable.html |Observable]] care pot fi subclasate pentru a implementa propriile tipuri de obiecte ce trebuie monitorizate și observatorii acestora. | API-ul Java oferă clasele [[http://docs.oracle.com/javase/8/docs/api/java/util/Observer.html |Observer]] și [[http://docs.oracle.com/javase/8/docs/api/java/util/Observable.html |Observable]] care pot fi subclasate pentru a implementa propriile tipuri de obiecte ce trebuie monitorizate și observatorii acestora. | ||
Line 628: | Line 628: | ||
**Task 1 - Observer, Strategy, Factory (8p) ** | **Task 1 - Observer, Strategy, Factory (8p) ** | ||
- | **Part 1. (4p) - Strategy, Factory** | + | **Part 1. (4p) - Strategy, Factory ** |
- | În cadrul acestui exercițiu, dorim să implementăm un magazin, ce are disponibile mai multe modalități de plată pentru clienții săi (folosind un voucher, IBAN-ul sau un card pe care îl posedă). | + | În cadrul acestui exercițiu, dorim să implementăm un magazin, ce are disponibile mai multe modalități de plată pentru clienții săi: |
- | Cele 3 modalități de plată sunt reprezentate de clase ce implementează interfața PaymentStrategy. | + | * folosind un voucher |
+ | * IBAN-ul | ||
+ | * un card pe care îl posedă | ||
+ | |||
+ | Cele 3 modalități de plată sunt reprezentate de clase ce implementează interfața **PaymentStrategy**. | ||
Trebuie să implementați: | Trebuie să implementați: | ||
- | * Metoda pay din cadrul fiecărei metode de plată. | + | * metoda **pay** din cadrul fiecărei metode de plată. |
- | * Metoda getPaymentMethod, ce primește un client ca parametru și instanțiază o tranzacție folosind o anumită metodă de plată, aleasă random. | + | * metoda **getPaymentMethod**, ce primește un client ca parametru și instanțiază o tranzacție folosind o anumită metodă de plată, aleasă random. |
- | <note tip> **HINT:** getPaymentMethod va fi folosită în cadrul unei metode ce trebuie implementată în cadrul părții de Observer </note> | + | |
- | | ||
- | **Part 2. (4p) - Observer** | ||
- | În acest context, subiectul (cel care este Observable) este clasa Person. Această clasă implementează interfața BalanceObserver (care este Observer-ul). Clasa Shop (ce joacă rol de Publisher, întrucât implementează interfața TransactionPublisher) va avea rolul de a notifica un client când o tranzacție este efectuată. | + | **Part 2. (4p) - Observer ** |
+ | |||
+ | În acest context, **subscriber-ul/observer-ul** este clasa Person. Această clasă implementează interfața **BalanceObserver**. Clasa Shop, care este **subiectul/publisher-ul** care trebuie să implementeze interfața **TransactionPublisher** va avea rolul de a **notifica** un client când o tranzacție este efectuată. | ||
Trebuie să implementați: | Trebuie să implementați: | ||
- | *Motoda update din cadrul clasei Person, ce notifică faptul că un client are în cont mai puțini Lei decât o anumită limită, specifică fiecărui client în parte, printr-un mesaj adecvat ("<nume> <prenume>, ramai fara bani, saracule!"). | + | * metoda **update** din cadrul clasei **Person**, ce preia notificarea faptului că un client are în cont mai puțini Lei decât o anumită limită, specifică fiecărui client în parte, printr-un mesaj adecvat (”$nume$ $prenume$, ramai fara bani, saracule!”); |
- | *Metoda payBy din cadrul clasei Person, ce întoarce valoarea de adevăr a reușitei efectuării unei plăți (dacă e posibil efectuează plata), iar în caz negativ afisează și un mesaj adecvat ("<nume> <prenume>, pleaca de aici, saracule!"). | + | * metoda **payBy** din cadrul clasei Person, ce întoarce valoarea de adevăr a reușitei efectuării unei plăți (dacă e posibil, efectuează plata), iar în caz negativ afisează și un mesaj adecvat (”$nume$ $prenume$, pleaca de aici, saracule!”); |
- | *Metoda createTransaction din cadrul clasei Shop, ce verifică dacă trebuie notificată persoana cu ajutorul metodei update, în urma unei tranzacții. | + | * metoda **createTransaction** din cadrul clasei **Shop**, ce verifică dacă trebuie notificată persoana cu ajutorul metodei **update**, în urma unei tranzacții. |
- | <note tip> **HINT:** trebuie folosită și metoda payBy </note> | + | |
Line 655: | Line 657: | ||
**Task 2 - Builder pattern (2p)** | **Task 2 - Builder pattern (2p)** | ||
- | a) Scrieți câmpuri în skeletul clasei House pentru câteva facilități obligatorii în construcția unei case, spre exemplu: locația construcției, numărul de etaje, încălzire, camere, dar și unele opționale pe care le poate selecta sau nu clientul, cum ar fi electrocasnice, piscină, panouri solare, securitate etc. | ||
- | Completați constructorul privat, metodele de get și metoda toString. | + | a) Examinați câmpurile din skeletul clasei **House** care includ câteva facilități obligatorii în construcția unei case, spre exemplu: |
+ | |||
+ | * locația construcției | ||
+ | * numărul de etaje | ||
+ | * camere | ||
+ | * unele **opționale** pe care le poate selecta sau nu clientul, cum ar fi: | ||
+ | * electrocasnice | ||
+ | * piscină | ||
+ | * panouri solare | ||
+ | * securitate | ||
+ | Completați constructorul public și metoda toString. | ||
- | b) În clasa de builder, completați câmpurile, constructorul și metodele de adăugare | + | b) În clasa **HouseBuilder**, completați câmpurile, constructorul și metodele de adăugare a facilităților opționale. |
- | a facilităților opționale. | + | |
- | c) Finalizați metoda build și testați funcționalitatea într-o clasă Main creată de voi, acoperind cazuri în care se construiește o casa doar cu facilitați obligatorii și altele adăugând și pe cele opționale. | + | c) Finalizați metoda build și decomentați codul din Main pentru a putea testa corectitudinea funcționalității. |
**Task 3 - Command pattern (8p)** | **Task 3 - Command pattern (8p)** | ||
Line 675: | Line 686: | ||
* //Client// - entry-point-ul în program | * //Client// - entry-point-ul în program | ||
- | (4p) Implementați 5 tipuri de comenzi, pentru următoarele acțiuni: | + | (4p) Implementați 4 tipuri de comenzi, pentru următoarele acțiuni: |
* Draw rectangle - crează o DiagramComponent și o adaugă în DiagramCanvas | * Draw rectangle - crează o DiagramComponent și o adaugă în DiagramCanvas | ||
* Resize - modifică width și height al unei DiagramComponent pe baza unui procent dat | * Resize - modifică width și height al unei DiagramComponent pe baza unui procent dat |