This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
laboratoare:design-patterns2 [2020/01/05 17:31] Adriana Draghici |
laboratoare:design-patterns2 [2020/01/05 19:42] (current) Adriana Draghici [Exerciții] fixed typo |
||
---|---|---|---|
Line 3: | Line 3: | ||
== Obiective == | == Obiective == | ||
- | Scopul acestui laborator este familiarizarea cu folosirea deign pattern-ului comportamental //Command// | + | Scopul acestui laborator este familiarizarea cu folosirea design pattern-ului comportamental //Command//. |
Line 14: | Line 14: | ||
În acest laborator vom //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. | |
- | == Introducere == | + | |
- | + | ||
- | 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. | + | |
| | ||
Acest pattern este recomandat în următoarele cazuri: | Acest pattern este recomandat în următoarele cazuri: | ||
Line 30: | Line 27: | ||
* mecanism ordonat pentru delegare, apel întârziat, callback | * mecanism ordonat pentru delegare, apel întârziat, callback | ||
| | ||
- | === Funcționare și necesitate === | + | == Funcționare și necesitate == |
Î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ă). | Î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ă). | ||
| | ||
Line 39: | Line 36: | ||
//__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 a 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? ]] | ||