User Tools

Site Tools


Problem constructing authldap
laboratoare:design-patterns
Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
laboratoare:design-patterns [2019/12/02 16:05]
Adriana Draghici [Resurse]
laboratoare:design-patterns [2020/01/04 21:54] (current)
Adriana Draghici [Resurse] added solution
Line 181: Line 181:
  
 === Implementare === === Implementare ===
- 
-Un exemplu de implementare este [[.:​clase-interne#​exercitii|exercițiul 2]] de la laboratorul ​ 5 (Clase interne). Observați diagrama de clase asociată acestuia. ​ 
  
 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 ([[http://​www.programcreek.com/​2009/​01/​the-steps-involved-in-building-a-swing-gui-application/​|exemplu]]).
Line 209: Line 207:
 //​__Recomandare__//:​ Urmariti link-ul de la referinte catre postul de pe Stack Overflow care descrie necesitatea pattern-ului Strategy. Pe langa motivul evident de incapsulare a prelucrarilor/​algoritmilor (care reprezinta strategiile efective), se prefera o anumita abordare: la runtime se verifica mai multe conditii si se decide asupra strategiei. Concret, folosind mecanismul de polimorfism dinamic, se foloseste o anumita instanta a tipului de strategie (//ex. Strategy str = new CustomStrategy//​),​ care se paseaza in toate locurile unde este nevoie de Strategy. Practic, in acest fel, utilizatorii unei anumite strategii vor deveni agnostici in raport cu strategia utilizata, ea fiind instantiata intr-un loc anterior si putand fi gata utilizata. Ganditi-va la browserele care trebuie sa detecteze daca device-ul este PC, smartphone, tableta sau altceva si in functie de acest lucru sa randeze in mod diferit. Fiecare randare poate fi implementata ca o strategie, iar instantierea strategiei se va face intr-un punct, fiind mai apoi pasata in toate locurile unde ar trebui sa se tina cont de aceasta strategie. //​__Recomandare__//:​ Urmariti link-ul de la referinte catre postul de pe Stack Overflow care descrie necesitatea pattern-ului Strategy. Pe langa motivul evident de incapsulare a prelucrarilor/​algoritmilor (care reprezinta strategiile efective), se prefera o anumita abordare: la runtime se verifica mai multe conditii si se decide asupra strategiei. Concret, folosind mecanismul de polimorfism dinamic, se foloseste o anumita instanta a tipului de strategie (//ex. Strategy str = new CustomStrategy//​),​ care se paseaza in toate locurile unde este nevoie de Strategy. Practic, in acest fel, utilizatorii unei anumite strategii vor deveni agnostici in raport cu strategia utilizata, ea fiind instantiata intr-un loc anterior si putand fi gata utilizata. Ganditi-va la browserele care trebuie sa detecteze daca device-ul este PC, smartphone, tableta sau altceva si in functie de acest lucru sa randeze in mod diferit. Fiecare randare poate fi implementata ca o strategie, iar instantierea strategiei se va face intr-un punct, fiind mai apoi pasata in toate locurile unde ar trebui sa se tina cont de aceasta strategie.
  
 +== Summary ==
  
 +* Principii de design adresate de aceste patternuri:​ 
 +  * [[https://​stackoverflow.com/​questions/​62539/​what-is-the-dependency-inversion-principle-and-why-is-it-important|Dependency Injection Principle]] - componentele trebuie să depindă de tipuri abstracte, nu de implementări 
 +    * Factory respectă acest principiu, componentele depinzând de interfața pentru un tip, nu de un subtip anume 
 +  * Separarea codului care se schimbă de cel care rămâne la fel - în cazul Strategy folosim o interfață pentru strategii, depindem de aceea, si putem schimba implementările fără a modifica codul care le folosește ([[https://​www.freecodecamp.org/​news/​the-strategy-pattern-explained-using-java-bc30542204e0/​|exemplu]]) 
 +  * [[http://​thephantomprogrammer.blogspot.com/​2015/​07/​strive-for-loosely-coupled-design.html|Loosly coupled design]] - în cazul Observer componentele sunt slab legate între ele
  
  
  
 == Exerciții == == Exerciții ==
-Soon... 
  
 +În cadrul acestui laborator veți implementa o aplicație //mock// care primește date și le procesează.
 +
 +Arhitectura ei va include patternurile Observer, Strategy și Factory și este descrisă în README-ul din
 +arhiva dată cu scheletul de cod.
 +
 +
 +** Task 1 - Observer pattern (3p) **
 +
 +Scheletul de cod vă oferă clasele //MainApp// (entry-point pentru testare), //Utils// și //​DataRepository//​.
 +
 +''​DataRepository''​ este obiectul observabil, care va primi date noi de la MainApp. Când acesta primește date noi va notifica observatorii săi: ''​ConsoleLogger'',​ ''​ServerCommunicationController''​ și ''​DataAggregator''​.
 +* Pentru a avea deja mecanismul de notificare vom folosi interfața [[https://​docs.oracle.com/​en/​java/​javase/​11/​docs/​api/​java.base/​java/​util/​Observer.html|Observer]] și clasa [[https://​docs.oracle.com/​en/​java/​javase/​11/​docs/​api/​java.base/​java/​util/​Observable.html|Observable]] din java.util. Dacă doriți și aveți timp puteți să vă implementați propriile interfețe Oberver-Observable.
 +   * Observer-Observable din java.util sunt deprecated din java 9 pentru că sunt prea simple, însă asta le face potrivite pentru acest laborator. Într-o aplicație reală puteți folosi alte api-uri care sunt mult mai complexe și oferă foarte multe tipuri de obiecte și mecanisme (termenul folosit este //reactive programming//​).
 +* Citiți în [[https://​github.com/​oop-pub/​laboratoare/​blob/​master/​design-patterns/​skel/​src/​README|README]] rolul fiecărui observator.
 +* //Hint:// vedeți metodele din [[https://​docs.oracle.com/​en/​java/​javase/​11/​docs/​api/​java.base/​java/​util/​Observable.html|Observable]] pentru notificarea observatorilor,​ schimbarea stării obiectului observat și adăugarea de observatori.
 +
 +
 +** Task 2 - Strategy pattern (3p)**
 +
 +Scheletul vă oferă interfața ''​StepCountStrategy''​ ce va fi implementată de către "​algoritmii"​ de prelucrare a datelor: ''​BasicStepCountStrategy''​ și ''​FilteredStepCountStrategy''​. Prima adună toate valorile primite, iar a doua le adună doar pe cele ce îndeplinesc niște condiții (să fie număr pozitiv și să nu fie o valoare prea mare (mai mult de 1000 de pași) venită prea curând de la ultimul update primit (în mai puțin de 1 minut).
 +   * strategiile vor folosi datele stocate în DataRepository
 +   * pentru strategia Filtered puteți folosi următoarele constante: ''​ private static final int MAX_DIFF_STEPS_CONSECUTIVE_RECORDS = 1000;''​ și ''​private static final long TIME_FOR_MAX_DIFF = TimeUnit.SECONDS.toMillis(1);''​
 +
 +
 +** Task 3 - Factory pattern (2p)**
 +
 +Creați clasa ''​StepCountStrategyFactory''​ care construiește instanțe de subclase ale StepCountStrategy.
 +
 +Clasa factory va conține o metodă care să întoarcă o strategie. De exemplu:
 +''​public StepCountStrategy createStrategy(String strategyType,​ DataRepository dataRepository)''​. StrategyType poate fi un string care să indice tipul strategiei, vedeți în ''​Utils''​ stringurile definite deja.
 +
 +** Task 4 - Putting all together (2p)**
 +
 +Realizați TODO-urile din codul de test din MainApp și rulați. Puteți să vă adăugați propriile exemple de date pentru a verfica corectitudinea programului.
 +
 +
 +
 + 
 == Resurse == == Resurse ==
  
 +* {{ :​laboratoare:​design-patterns:​design-patterns-part1-skel.zip |Schelet}}
 +* {{ :​laboratoare:​design-patterns:​lab-design-patterns1-sol.zip | Soluție}}
 * [[laboratoare:​old-exercises|Exerciții din alți ani]] * [[laboratoare:​old-exercises|Exerciții din alți ani]]
  
Line 227: Line 269:
 *  [[http://​sourcemaking.com/​design_patterns/​observer/​java/​1 | Exemple simple pattern Observer]] ​ *  [[http://​sourcemaking.com/​design_patterns/​observer/​java/​1 | Exemple simple pattern Observer]] ​
 * [[http://​sourcemaking.com/​design_patterns/​observer | Explicații pattern Observer]]. * [[http://​sourcemaking.com/​design_patterns/​observer | Explicații pattern Observer]].
 +* [[https://​stackoverflow.com/​questions/​1710809/​when-and-why-should-the-strategy-pattern-be-used | De ce avem nevoie de Strategy Pattern? ]]
  
 /* exercitii 2012 /* exercitii 2012
laboratoare/design-patterns.1575295514.txt.gz · Last modified: 2019/12/02 16:05 by Adriana Draghici