2. Definiție
• În programare , un șablon de proiectare (design pattern) este o soluție generală la o
problemă concretă ce ține de proiectarea software.
• Un șablon de proiectare nu este un design finisat care poate fi transformat direct în
cod.
• El este o descriere sau un model pentru rezolvarea unei probleme care poate fi
utilizată în mai multe și diferite situații.
• Un şablon este descris de patru elemente:
– Nume: foloseşte pentru identificare, descrie sintetic problema rezolvată de şablon şi
soluţia.
– Problema: descrie când se aplică şablonul, se descrie problema şi contextul.
– Soluția: descrie elementele care intră în rezolvare, relaţiile între ele,
responsabilităţile lor şi colaborările între ele.
– Consecinţe si compromisuri: implicaţiile folosirii şablonului, costuri şi beneficii.
Acestea pot privi impactul asupra flexibilităţii, extensibilităţii sau portabilităţii
sistemului, după cum pot să se refere la aspecte ale implementării sau limbajului de
programare utilizat. Compromisurile sunt de cele mai multe ori legate de spaţiu şi
timp.
3. Clasificare
• Clasificarea bazata pe scop:
– Creaționale – se referă la procesul de creare a claselor și obiectelor.
– Structurale – se referă la compoziția claselor și a obiectelor.
– Comportamentale – caracterizează interacțiunea și responsabilitățile claselor și
obiectelor.
• Clasificarea bazată pe domeniu:
– Șabloanele claselor se referă la relaţii dintre clase, relaţii stabilite prin moştenire şi
care sunt statice (fixate la compilare).
• Şabloanele creaţionale ale claselor acoperă situaţiile în care o parte din procesul creării
unui obiect cade în sarcina subclaselor.
• Şabloanele structurale ale claselor descriu modul de utilizare a moştenirii în scopul
compunerii claselor.
• Şabloanele comportamentale ale claselor utilizează moştenirea pentru descrierea unor
algoritmi şi fluxuri de control.
4. Clasificare
• Clasificarea bazată pe domeniu:
– Şabloanele obiectelor se referă la relaţiile dintre obiecte, relaţii care au un caracter
dinamic.
• Şabloanele creaţionale ale obiectelor acoperă situaţiile în care o parte din procesul
creării unui obiect cade în sarcina unui alt obiect.
• Şabloanele structurale ale obiectelor descriu căile prin care se asamblează obiecte.
• Şabloanele comportamentale ale obiectelor descriu modul în care un grup de obiecte
cooperează pentru a îndeplini o sarcină ce nu ar putea fi efectuată de un singur obiect.
6. Singleton
• Scop
– Asigură că o clasă are o singură instanță și oferă un punct global de acces la ea.
– Încapsularea are loc doar în timpul utilizării sau initializarea la prima utilizare.
• Aplicabilitate
Singleton se foloseste când se lucrează cu o singura instanță a unei clase,
care trebuie sa fie disponibilă oriunde în aplicație.
• Descriere
Singleton asigură ca maximum o instanță este creată (din acest motiv este
numit singleton). Pentru a garanta controlul asupra instanțierii, constructorul este
făcut privat.
7. Singleton
• Implementare
class Singleton
{
private static Singleton instance;
private Singleton()
{
...
}
public static synchronized Singleton getInstance()
{
if (instance == null)
instance = new Singleton();
return instance;
}
...
public void doSomething()
{
...
}
}
8. Singleton
• Avantaje și dezavantaje
– Avantaje
• Singleton este singura clasă care poate crea o instanță a sa. Singura modalitate de creare
este prin apelarea metodei statice oferită de ea.
• Referința nu trebuie transmisă tuturor obiectelor interesate. Fiecare obiect ce are nevoie de
Singleton va apela metoda statică.
– Dezavantaje
• Șablonul Singleton poate provoca probleme de threading, ce depind de implementare.
Trebuie controlată cu atentie initializarea singletonului într-o aplicatie multithreading. Fără
un control adecvat, aplicația va beneficia de "războaie ale firelor de execuție".
9. Builder
• Scop
– Simplificarea crearii obiectelor prin definirea unei clase a carei scop este să
construiască instanțe ale altei clase.
– Builder produce un produs principal, în produs pot fi mai multe clase, dar există
întotdeauna o clasă principală.
• Aplicabilitate
șablonul Builder se foloseste când o clasă:
– Are o structură internă complexă (în special una cu o multime variabilă de obiecte
înrudite).
– Are atribute ce depind unul de altul. Unul din lucrurile ce le poate face un Builder
este să întărească construirea în etape succesive a unui obiect complex. Aceasta ar fi
necesară când atributele obiectului Product depind unul de altul. Foloseste alte
obiecte din sistem care ar putea fi greu de obținut în timpul creării.
• Descriere
– Deoarece acest șablon este dedicat construirii de obiecte complexe din surse posibil
diferite, el se numeste Builder.
– Clasa Builder coordonează asamblarea obiectului produs: crearea resurselor,
memorarea rezultatelor intermediare si furnizarea structurii functionale pentru creare.
Suplimentar, Builder poate achizitiona resurse sistem pentru construirea obiectului
produs.
10. Builder
• Implementare
Pentru implementarea șablonului Builder, este nevoie de:
Director - Are o referință la o instanță Builder. Obiectul Director apelează metodele creaționale
folosind instanța sa builder pentru a obține diversele părți din care se asamblează apoi obiectul produs.
Builder - interfața care definește metodele disponibile pentru crearea partilor separate ale produsului.
ConcreteBuilder - Clasa ce implementează interfața Builder. Clasa ConcreteBuilder
implementeaza toate metodele necesare pentru crearea unui obiect Product real. Implementarea metodelor stie cum sa
prelucreze informația din obiectul Director si construieste partile respective ale obiectului Product. Clasa
ConcreteBuilder are fie o metodă getProduct, fie o metoda creationala ce întoarce o instanta a clasei Product.
Product - Obiectul produs. Poate fi fie interfața (de preferat), fie clasa
11. Builder
• Avantaje și dezavantaje
– Avantaje
șablonul Builder simplifică gestionarea fluxului general de creare a obiectelor
complexe. Aceasta simplificare se manifestă în două moduri:
• Pentru obiectele ce impun o creare pas cu pas (este necesar un sir de pasi pentru a face
obiectul complet activ), Builder actioneaza ca un obiect de nivel mai înalt care supervizeaza
procesul de creare. El poate coordona si valida crearea tuturor resurselor si, la nevoie, poate
furniza o strategie de avarie la aparitia erorilor.
• Pentru obiectele care au nevoie la crearea lor de resurse sistem, precum conexiunile la BD
sau la BO existente, sablonul Builder ofera un punct central de gestiune a resurselor. De
asemenea, Builder se constituie într-un punct unic de control creational pentru produsul
sau, care poate fi folosit de alte obiecte din sistem. Ca si în cazul altor sabloane creationale,
aceasta abordare simplifica lucrurile pentru clientii sistemului, deoarece ei au nevoie doar
de acces la obiectul Builder pentru a produce o resursa.
– Dezavantaje
• Dezavantajul major este prezenta unei cuplari strânse între sablonul Builder, produsul sau si
orice alti delegati creationali folositi la construirea obiectului. Modificarile care se fac
pentru produsul creat de Builder implica de obicei modificari în Builder si în delegati.
12. Factory Method
• Scop
– Definește o interfață pentru a crea un obiect, dar lasă subclasele să decidă ce clasă
să fie instanțiată.
– Definirea unui constructor “virtual”.
• Aplicabilitate
șablonul Method Factory se foloseste când:
– se doreste crearea unui cadru (framework) flexibil. Flexibilitatea se obtine prin
amânarea luării unor decizii (ca de exemplu ce tip de obiect se creeaza) pentru mai
târziu;
– se doreste ca o subclasa sa decida ce tip de obiect se creeaza (si nu superclasele
sale);
– se stie când trebuie sa se creeze un obiect, dar nu se cunoaste ce fel de obiect trebuie
creat;
– este nevoie de mai multi constructori cu aceeasi lista de parametri, lucru nepermis în
Java. În locul acestora se folosesc metode Factory cu nume diferite.
• Descriere
– șablonul se numeste metoda Fabrica deoarece el creeaza (fabrica) obiecte la cerere.
13. Factory Method
• Implementare
Pentru a implementa sablonul metoda Factory, avem nevoie de urmatoarele:
Product - Interfata tuturor obiectelor create de fabrica.
ConcreteProduct - Clasa ce implementeaza interfata Product; nu are nevoie de constructor deoarece
obiectele sale sunt create de ConcreteCreator.
Factory - Interfata ce defineste metoda (metodele) Factory (factoryMethod). Aceasta metoda returneaza un
obiect ce implementeaza interfata Product.
ConcreteFactory- Clasa care implementeaza interfata Creator, furnizând implementarea pentru
factoryMethod.
14. Factory Method
• Avantaje și dezavantaje
– Avantaje
• JDBC (Java DataBase Connectivity) foloseste sablonul metoda Fabrica în multe dintre
interfetele sale. Se pot folosi diverse drivere JDBC, cu singura conditie ca oricare din ele sa
implementeze interfata dorita; restul aplicatiei nu este afectat.
– Dezavantaje
• Ori de câte ori apare un element de informatie (Product) nou, trebuie adaugata o clasa ce-l
implementeaza (ConcreteProduct) si o clasa ce implementeaza metoda Fabrica
corespunzatoare acestuia (ConcreteCreator).
15. Prototype
• Scop
– Face mai ușoara crearea dinamică a obiectelor prin definirea de clase ale căror
obiecte pot crea duplicate ale lor.
• Aplicabilitate
Șablonul Prototype se folosește când se dorește crearea unui obiect care este copie a
unuia existent.
• Descriere
– Șablonul Prototype este bine numit; la fel ca si în cazul altor prototipuri, el are ca
argument un obiect care este folosit ca baza pentru a crea o nouă instanță cu aceeași
stare.
– Exemple clasice ale acestui șablon există în editoarele text și grafice, unde
operațiile copy-paste pot îmbunătăți dramatic productivitatea utilizatorului.
16. Prototype
• Implementare
Pentru a implementa sablonul Prototype, avem nevoie de urmatoarele:
Prototype - Furnizeaza o metoda clone. Aceasta metoda returneaza o instanta a aceleiasi clase si cu aceeasi stare
ca si instanta Prototype initiala. Noua instanta poate fi o copie de adâncime sau de suprafata a originalului (vezi sectiunea
Avantaje si dezavantaje).
17. Prototype
sd sequence
:Client original:Prototype copied:Prototype
Create new instance
and copy all attributes
of the current instance.
Then return the new
instance.
Prototype copied;
copied=original.copy();
create()
copy attributes()
• Avantaje și dezavantaje
Șablonul Prototype este util deoarece el permite sistemelor să facă copii ale
obiectelor folosibile, cu variabilele de stare setate la o valoare (ipotetic) semnificativă, în loc
să creeze obiecte cu o stare de bază definită în constructor. Un exemplu de folosire a acestui
șablon este ilustrat în figura de mai sus.
18. Adapter
• Scop
– Convertește interfața unei clase într-o altă interfață necesară clientului.
– Oferă unei clase existente o nouă interfață.
– Adapter face posibil ca două clase să lucreze împreună, lucru care altfel nu ar fi
posibil din cauza interfețelor incompatibile.
• Comparație
– Adapterul de obiecte este mai flexibil
• Poate adapta nu numai clasa Adaptee, ci și orice clasă derivată a acesteia.
– Adapterul de clase este mai eficient
• Un singur obiect adaptor vs. două obiecte: un adaptor și un adaptat.
19. Adapter
• Adapter de obiecte și de clase
class Use Case View
Client «interface»
Target
+ Request() : void
• Adapter de obiecte
Adapter Adaptee
-_adaptee
- _adaptee:Adaptee: int* + SpecificRequest() : int
+ Request() : void
class Use Case View
Client «interface» Adaptee
Target
+ SpecificRequest() : int
+ Request() : void
• Adapte de clase
Adapter
+ Request() : void
20. Adapter
• Implementare
Adapter de obiecte Adapte de clase
Clase și obiecte prezente în șablon:
Target – definește domeniul – specifică ionterfața pe care Client o utilizează.
Adapter – adaptează interfața Adaptee la interfața Target.
Adaptee – definește o interfață existentă care trebuie adaptată.
Client – colaborează cu obiectele în conformitate cu interfața Target.
21. Facade
• Scop
– Șablonul Fațadă asigură o interfață unificată la o mulțime de interfețe dintr-un
subsistem.
– Fațada definește o interfață de nivel mai înalt care face subsistemul mai ușor de
utilizat.
• Discuție
– Fațada nu numai că simplifică o interfață, ci și decuplează clientul de subsistemul de
componente
• Subsistemul poate fi de asemenea accesat direct, fațada nu încapsulează
subsistemul.
– Atât Fațada cât și Adaptorul pot împacheta (pot fi wrappere pentru) una sau mai
multe clase
• Scopul Adaptorului este să convertească interfața.
• Scopul Fațadei este să simplifice interfața.
22. Facade
• Diagrama UML a șablonului
class Use Case View
Client Facade
Subsystem
Class7
Class8
Class10
Class9
Class5 Class6
23. Visitor
• Scop
– Reprezintă o operație care va fi efectuată pe elementele unei structuri de obiecte.
– Visiter permite definirea unei operații noi fără a schimba clasele elementelor pe care
operează.
• Aplicabilitate
– Când o structură de obiecte conține multe clase cu interfețe diferite.
– Când pe obiectele dintr-o structură trebuie efectuate mai multe operații neînrudite.
• Nu se “poluează” clasele cu aceste operații.
– Când se definesc des noi operații pe structură, dar clasele structurii nu se modifică des.
– Dacă o clasă nu are metoda Accept, se poate deriva pentru a o adăuga.
• Șablonul este util când nu se pot modifica sursele unor biblioteci sau platforme pentru adăugarea
unor noi funcții.
• Descriere
– Vizitatorul poate fi utilizat la aplicarea unei operații pe o structură Compusă (engl.
“Composite”)
– Pentru vizitarea fiecărui element al unei colecții se poate folosi Iteratorul acesteia
– Vizitatorul poate fi utilizat pentru a păstra într-o singură clasă comportarea fiecărui nod din
arborele sintactic al unui Interpretor
24. Visitor
• Implementare
Principalele clase ale acestui șablon sunt:
Visitor- Aceasta este o interfaţă
sau o clasă abstractă utilizată pentru a declara
operaţiunile de vizita pentru toate tipurile de clase
care pot fi vizitate.
ConcreteVisitor - Pentru fiecare
tip de vizitator toate metodele de vizita, trebuie să
fie implementate. Fiecare vizitator va fi responsabil
pentru diferite operaţiuni. Când un vizitator nou
este definit acesta trebuie să fie trecut la structura
obiectului.
Element - este o abstractizare care
declară operaţiunea acceptată. Acesta este punctul
de intrare, care permite unui obiect să fie "vizitat"
de către obiect vizitator.
ConcreteElement - Aceste clase
implementează interfața Visitable sau clasa şi
definesc operaţiunea acceptată.
ObjectStructure – aceasta este o
clasă care conține toate obiectele care pot fi vizitate.
25. Visitor
• Avantaje și dezavantaje
– Avantaje
• Facilitează adăugarea de operații noi.
• Grupează operațiile înrudite și le separă pe cele neînrudite.
• Vizitatorul poate vizita obiecte care nu au o clasă părinte comună, spre deosebire de Iterator.
– Se pot apela metode diferite în Vizitator în funcție de tipul obiectului vizitat.
– Alternativa ar fi testarea tipului obiectului.
• Poate acumula starea pe măsură ce vizitează obiectele.
• Pot exista mai mulți vizitatori într-un sistem.
• Apelul bidirecțional Accept - Visit permite adăugarea mai multor operații la vizitare.
– Dezavantaje
• Adăugarea de noi clase ConcreteElement este dificilă
– Șablonul nu este recomandat în timpul dezvoltării unui sistem, când numărul de clase crește
sau clasele se modifică mult
• Poate reduce încapsularea, obligând obiectele vizitate să-și expună starea internă
– Vizitatorul nu poate accesa câmpurile private, deci trebuie să existe metode publice de
acces în obiectele vizitate
• Antișablonul de proiectare “Anemic domain model” (când logica programului este implementată
în afara obiectelor din domeniu)
26. Iterator
• Scop
– Șablonul Iterator asigură o cale de accesare secvențială a elementelor unui obiect
agregat, fără a expune reprezentarea lui de bază.
• Discuție
– Metodele Iteratorului pot avea nume diferite
• Java Iterator: next(), hasNext(), remove()
• C# IEnumerator: Current, MoveNext(), Reset()
– Există Iteratori interni și externi Iteratorul extern este controlat de client
• Iteratorul intern este controlat de Iteratorul însuși, căruia trebuie să i se spună ce operații să
efectueze cu elementele pe care le parcurge
– Utilizat mai ales în limbaje ca Lisp, Smalltalk etc. sau când se pot trimite ca parametri funcții
anonime pentru operații
27. Iterator
• Aplicabilitate
– Șablonul se utilizează pentru:
• A accesa conținutul unui obiect agregat fără a expune reprezentarea internă
• A asigura suport pentru mai multe traversări ale obiectelor agregate
• A furniza o interfață uniformă pentru traversarea structurilor agregate diferite
– Pentru a suporta o iterație polimorfică
• Avantaje
– Suportă variații în traversarea unui agregat
• Obiectele agregate pot fi traversate în mai multe feluri și de mai multe ori.
– Obiectele Iterator simplifică interfața Agregat
• Agregatul are nevoie de o metodă unică pentru crearea Iteratorului.
– Scade cuplarea dintre client și obiectele agregate.
– În cazul Iteratorului extern, crește coeziunea obiectului agregat prin eliminarea
necesității de a asigura el însuși traversarea.