User Tools

Site Tools


Problem constructing authldap
laboratoare:design-patterns2
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-patterns2 [2020/01/05 17:25]
Adriana Draghici [Builder]
laboratoare:design-patterns2 [2020/01/05 19:42] (current)
Adriana Draghici [Exerciții] fixed typo
Line 1: Line 1:
-= Design patterns - Command, Builder ​=+= Design patterns - Command =
  
 == Obiective == == Obiective ==
  
-Scopul acestui laborator este familiarizarea cu folosirea ​unor pattern-uri des întâlnite în design-ul atât al aplicațiilor,​ cât și al API-urilor - //Command// și //Builder//.+Scopul acestui laborator este familiarizarea cu folosirea ​design ​pattern-ului comportamental ​//​Command//​.
  
  
Line 12: Line 12:
   * pattern-uri comportamentale ce decuplează comunicarea dintre componente: [[.visitor#​visitor|Visitor]],​ [[.design-patterns#​observer-pattern|Observer]],​ [[design-patterns#​strategy-pattern|Strategy]]   * pattern-uri comportamentale ce decuplează comunicarea dintre componente: [[.visitor#​visitor|Visitor]],​ [[.design-patterns#​observer-pattern|Observer]],​ [[design-patterns#​strategy-pattern|Strategy]]
  
-În acest laborator vom mai prezenta înca două patternuri, //​Builder,//​ folosit foarte mult, mai ales în API-uri, pentru construirea obiectelor, și //​Command//,​ un pattern comportamental care decuplează obiectele care execută anumite acțiuni de obiectele care le invocă.+În acest laborator vom //​Command//,​ un pattern comportamental care decuplează obiectele care execută anumite acțiuni de obiectele care le invocă.
  
- +Design pattern-ul //​Command// ​incapsulează un apel cu tot cu parametri într-o clasă cu interfată generică. Acesta este //​Behavioral//​ pentru ​că modifică interacțiunea dintre componente, mai exact felul în care se efectuează apelurile. ​  
-== Command Pattern == +   
- + Acest pattern este recomandat în următoarele cazuri: ​  
-Design pattern-ul //​Command// ​încapsulează un apel cu tot cu parametri într-o clasă cu interfață generică. Acesta este //​Behavioral//​ pentru ​ca modifică interacțiunea dintre componente, mai exact felul în care se efectuează apelurile.  + * pentru a ușura crearea de structuri de delegare, de callback, de apelare ​intarziată  
- + * pentru a reține lista de comenzi efectuate asupra obiectelor  
-Acest pattern este recomandat în următoarele cazuri:  +     ​* accounting  
-* pentru a ușura crearea de structuri de delegare, de callback, de apelare ​întârziată +     ​* liste de Undo, Rollback pentru tranzacții-suport pentru operații reversibile (//undoable operations//​)  
-* pentru a reține lista de comenzi efectuate asupra obiectelor +   
-    * accounting + ​Exemple de utilizare:  
-    * liste de Undo, Rollback pentru tranzacții - suport pentru operații reversibile (//undoable operations//​) + * sisteme de logging, accounting pentru tranzacții  
- + * sisteme de undo (ex. editare imagini)  
-Exemple de utilizare:​ + * mecanism ordonat pentru delegare, apel întârziat,​ callback  
-* sisteme de logging, accounting pentru tranzacții +   
-* sisteme de undo (ex. editare imagini) +== Funcționare și necesitate ==  
-* mecanism ordonat pentru delegare, apel întârziat,​ callback +În esentă, Command pattern (așa cum v-ați obișnuit și lucrând ​cu celelate Pattern-uri pe larg cunoscute) presupune ​încapsularea ​unei informații ​referitoare la acțiuni/comenzi folosind un wrapper pentru a "ține minte această informație" ​și pentru a o folosi ulterior. Astfel, un astfel de wrapper va deține informații ​referitoare la tipul acțiunii ​respective (în general un asemenea wrapper va expunde o metodă ​execute(), care va descrie comportamentul pentru ​acțiunea respectivă).  
- +   
-=== Functionare si necesitate ​=== +Mai mult încăcând vorbim de Command Pattern, ​în terminologia OOP o să întâlniți ​deseori ​și noțiunea ​de //Invoker//. Invoker-ul este un middleware ca funcționalitate ​care realizează ​managementul comenzilor. Practic, un //Client//, care vrea să facă anumite ​acțiune, va instanția ​clase care implementează ​interfață //Command//. Ar fi incomod ca, în cazul în care aceste ​instanțieri ​de comenzi provin din mai multe locuri, acest management de comenzi ​să se facă local, ​în fiecare parte (din rațiuni ​de economie, nu vrem să duplicăm ​cod). Invoker-ul apare ca o necesitate de a centraliza acest proces ​și de a realiza intern management-ul comenzilor (le ține într-o listăține cont de eventuale ​dependințe între ​ele, totul în funcție ​de context).  
-In esenta, Command pattern (asa cum v-ati obisnuit si lucrand ​cu celelate Pattern-uri pe larg cunoscute) presupune ​incapsularea ​unei informatii ​referitoare la actiuni/comenzi folosind un wrapper pentru a "tine minte aceasta informatie" ​si pentru a o folosi ulterior. Astfel, un astfel de wrapper va detine informatii ​referitoare la tipul actiunii ​respective (in general un asemenea wrapper va expunde o metoda ​execute(), care va descrie comportamentul pentru ​actiunea respectiva). +   
- +Un client (generic spus, un loc de unde se lansează ​comenzi) ​instanțiază ​comenzile ​și le pasează ​Invoker-ului. Din acest motiv Invoker-ul este un middleware ​între ​client ​și receiver, ​fiindcă ​acesta va apela execute pe fiecare Command, ​în funcție ​de logica ​să internă
-Mai mult incacand vorbim de Command Pattern, ​in terminologia OOP o sa intalniti ​deseori ​si notiunea ​de Invoker. Invoker-ul este un middleware ca functionalitate ​care realizeaza ​managementul comenzilor. Practic, un Client, care vrea sa faca anumite ​actiune, va instantia ​clase care implementeaza ​interfata ​Command. Ar fi incomod ca, in cazul in care aceste ​instantieri ​de comenzi provin din mai multe locuri, acest management de comenzi ​sa se face local, ​in fiecare parte (din ratiuni ​de economie, nu vrem sa duplicam ​cod). Invoker-ul apare ca o necesitate de a centraliza acest proces ​si de a realiza intern management-ul comenzilor (le tine intr-o listatine cont de eventuale ​dependinte intre ele, totul in functie ​de context). +
- +
-Si nu in cele din urma, un client (generic spus, un loc de unde se lanseaza ​comenzi) ​instantiaza ​comenzile ​si le paseaza ​Invoker-ului. Din acest motiv Invoker-ul este un middleware ​intre client ​si receiver, ​fiindca ​acesta va apela execute pe fiecare Command, ​in functie ​de logica ​sa interna.+
  
 //​__Recomandare__//:​ La Referinte aveti un link catre un post pe StackOverflow,​ pentru a intelege mai bine de ce aveti nevoie de Pattern-ul Command si de ce nu lansati comenzi pur si simplu. //​__Recomandare__//:​ La Referinte aveti un link catre un post pe StackOverflow,​ pentru a intelege mai bine de ce aveti nevoie de Pattern-ul Command si de ce nu lansati comenzi pur si simplu.
  
- +== Structura ==
-=== Structura ​===+
  
 Ideea principală este de a crea un obiect de tip //Command// care va reține parametrii pentru comandă. Comandantul reține o referință la comandă și nu la componenta comandată. Comanda propriu-zisă este anunțată obiectului //Command// (de către comandant) prin execuția unei metode specificate asupra lui. Obiectul //Command// este apoi responsabil de trimiterea (//​dispatch//​) comenzii către obiectele care o îndeplinesc (//​comandați//​). ​ Ideea principală este de a crea un obiect de tip //Command// care va reține parametrii pentru comandă. Comandantul reține o referință la comandă și nu la componenta comandată. Comanda propriu-zisă este anunțată obiectului //Command// (de către comandant) prin execuția unei metode specificate asupra lui. Obiectul //Command// este apoi responsabil de trimiterea (//​dispatch//​) comenzii către obiectele care o îndeplinesc (//​comandați//​). ​
Line 64: Line 60:
 În diagrama din <imgref cmd_image>,​ comandantul este clasa //Invoker// care conține o referință la o instanță (command) a clasei (Command). //Invoker// va apela metoda abstractă ''​execute()''​ pentru a cere îndeplinirea comenzii. //​ConcreteCommand//​ reprezintă o implementare a interfeței //​Command//,​ iar în metoda ''​execute()''​ va apela metoda din //​Receiver//​ corespunzătoare acelei acțiuni/​comenzi. În diagrama din <imgref cmd_image>,​ comandantul este clasa //Invoker// care conține o referință la o instanță (command) a clasei (Command). //Invoker// va apela metoda abstractă ''​execute()''​ pentru a cere îndeplinirea comenzii. //​ConcreteCommand//​ reprezintă o implementare a interfeței //​Command//,​ iar în metoda ''​execute()''​ va apela metoda din //​Receiver//​ corespunzătoare acelei acțiuni/​comenzi.
   ​   ​
-=== Implementare ​===+=== Exemplu ​===
  
 Diagrama de secvență din <imgref cmd_flow_image>​ prezintă apelurile în cadrul unei aplicație de editare a imaginilor, ce este structurată folosind pattern-ul Command. În cadrul acesteia, Receiver-ul este //Image//, iar comenzile //​BlurCommand//​ și //​CropCommand//​ modifică starea acesteia. Structurând aplicația în felul acesta, este foarte ușor de implementat un mecanism de undo/redo, fiind suficient să menținem în Invoker o listă cu obiectele de tip //Command// aplicate imaginii. ​ Diagrama de secvență din <imgref cmd_flow_image>​ prezintă apelurile în cadrul unei aplicație de editare a imaginilor, ce este structurată folosind pattern-ul Command. În cadrul acesteia, Receiver-ul este //Image//, iar comenzile //​BlurCommand//​ și //​CropCommand//​ modifică starea acesteia. Structurând aplicația în felul acesta, este foarte ușor de implementat un mecanism de undo/redo, fiind suficient să menținem în Invoker o listă cu obiectele de tip //Command// aplicate imaginii. ​
Line 105: Line 101:
 ** Task 3 - Undo/redo (2p) ** ** Task 3 - Undo/redo (2p) **
  
-Implementați în comenzi și în Invoker mecanismul de undo/redo al comenzilor. Recomandăm în Invoker sa folosiți două structuri de date, una care să mențină comenzile efectuate, iar una pentru ​comenzile făcute undo.+Implementați în comenzi și în Invoker mecanismul de undo/redo al comenzilor. Recomandăm în Invoker sa folosiți două structuri de date, una care să mențină comenzile efectuate, iar una pentru comenzile făcute undo.
  
 ** Task 4 - Test undo/redo (2p) ** ** Task 4 - Test undo/redo (2p) **
Line 112: Line 108:
  
  
 +/*
  
 +TODO pt 2020 (acum nu am avut timp):
 +- builder pattern in textul labului
 +- un exercitiu care sa ia exemplul de cod pus la partea de teorie si sa il ruleze si sa ii aplice doar o mica modificare
  
 +*/
  
 == Resurse == == Resurse ==
  
 +* {{ :​laboratoare:​design-patterns:​design-patterns-part2-skel.zip |Schelet}} 
 +* [[laboratoare:​old-exercises|Exerciții din alți ani]]
  
 == Referințe == == Referințe ==
  
-* [[http://​www.codeproject.com/​Articles/​15207/​Design-Patterns-Command-Pattern |Descriere Command Pattern si exemplu pentru operatii undo/​redo]] +* [[https://​sourcemaking.com/​design_patterns/​command | Command ​design ​pattern]]
-* [[https://​sourcemaking.com/​design_patterns/​command | O resursa buna pentru a intelege cele mai des intalnite ​design ​patterns]]+
 * [[https://​stackoverflow.com/​questions/​32597736/​why-should-i-use-the-command-design-pattern-while-i-can-easily-call-required-met | De ce avem nevoie de Command Pattern? ]] * [[https://​stackoverflow.com/​questions/​32597736/​why-should-i-use-the-command-design-pattern-while-i-can-easily-call-required-met | De ce avem nevoie de Command Pattern? ]]
  
  
laboratoare/design-patterns2.1578237901.txt.gz · Last modified: 2020/01/05 17:25 by Adriana Draghici