Curs 9 Curs 11

SABLOANE DE PROIECTARE

Constructorul (Builder)






Definitie
Este sablonul care descrie crearea unor obiecte in regim pas cu pas, in conditiile in care procesul de creare este independent de structura interna a obiectelor.

Context
Sa presupunem ca un anumit editor (de ex. Word) trebuie sa poate converti un document in mai multe formate de reprezentare, ca: ASCII, HTML, TeX etc.
Problema care apare aici este aceea ca numarul de reprezentari posibile nu este limitat si trebuie ca adaugarea unui nou tip de conversie sa nu afecteze restul editorului.
Sablonul Builder propune ca solutie definirea unei clase DocReader care va baleia documentul de convertit si a unei clase DocConverter care realizeaza conversia fiecarei unitati (caractere, specificatii de formatare etc) a documentului.
Unui obiect DocReader i se va asocia la un moment dat un obiect apartinand unei subclase a luiDocConverter. Fiecare subclasa a lui DocConverter corespunde unui anumit tip de conversie.

Motivatii

Sablonul Builder se aplica in situatiile in care:

algoritmul de creare a unui obiect complex trebuie sa fie independent de partile ce compun obiectul;
procesul de construire trebuie sa permita reprezentari diverse pentru obiectul implicat.


Solutie

In figura de mai jos este data structura de clase care constituie sablonul Builder:

Clientul creaza un obiect Director, pe care il configureaza (asociaza) cu un obiect Builder dorit.
Obiectul Director solicita obiectul Builder ori de cate ori trebuie creata o componenta a produsului.
Obiectul Builder receptioneaza cererea Director-ului si raspunde la ea prin crearea si adaugarea componentei la produs.
Clientul poate obtine produsul prin intermediul Builder-ului.
Aceste colaborari sunt ilustrate in diagrama de secventa de mai jos:


 

Consecinte

Sablonul Builder:

permite schimbarea reprezentarii interne pentru produs. Deoarece construirea produsului se face via o interfata abstracta (Builder), daca se doreste la un moment dat sa se treaca la o alta reprezentare interna, trebuie doar sa se asocieze Director-ul cu un alt obiect ConcreteBuilder;
izoleaza codul aferent construirii si reprezentarii. Aici este vorba de o aplicare a principiului modularitatii, prin faptul ca se incapsuleaza (in obiectele ConcreteBuilder) modul in care un obiect este construit si reprezentat. Clientii nu trebuie sa stie nimic despre clasele care definesc structura interna a produsului. Aceste clase nu apar in interfata Builder. Fiecare ConcreteBuilder contine intregul cod pentru a crea si asambla un anumit produs particular. Mai multe obiecte Director diferite pot reutiliza codul respectiv pentru a crea produse;
permite un control mai adanc asupra procesului de construire. Spre deosebire de alte sabloane creationale, care construiesc produsele "dintr-un foc", sablonul Builder construieste produsul pas cu pas, sub controlul obiectului Director. Doar cand produsul este gata, el poate fi obtinut de la constructor. Interfata Builder reflecta procesul de constructie mai in detaliu decat celelalte sabloane creationale.
Implementare
Interfata Builder trebuie sa prevada cate o operatie pentru fiecare componenta a produsului. In mod implicit aceste operatii nu fac nimic, urmand a fi redefinite de fiecare ConcreteBuilder dupa necesitati.

O problema importanta la acest sablon o constituie definirea modului de asamblare a componentelor produsului. In principiu exista 2 moduri de asamblare:

Dupa cum se observa din diagrama sablonului, nu exista o interfata comuna pentru produse. In practica, aceste produse sunt foarte diferite intre ele ca reprezentare, astfel incat nu s-ar justifica existenta unei clase parinte comune. In mod normal, clientul care ataseaza unui Director un ConcreteBuilder stie exact care este acel ConcreteBuilder si ce fel de produs creaza el.

Daca la implementare se utilizeaza limbajul C++, nu se recomanda ca metodele din Builder sa fie pur virtuale, deoarece clasele ConcreteBuilder trebuie lasate sa redefinesca doar acele metode de care au nevoie pentru a crea un anumit produs. De exemplu, cand un document este convertit in format ASCII, se vor prelucra doar caracterele de text propriu-zis, nu si specificatiile de "decorare" a textului sau de punere in pagina.


Obiecte unicat (Singleton)






Definitie
Creaza premizele ca o anumita clasa sa fie instantiata doar o singura data, permitandu-se un acces global la instanta respectiva.

Context
Exista situatii cand un anumit obiect trebuie sa existe doar intr-un singur exemplar. Spre exemplu, intr-o aplicatie gen File Manager, arborele director trebuie sa fie unul singur, orice modificare trebuind sa se reflecte in acest unic obiect.
Un alt exemplu, mai familiar poate, este legat de tema de la lucrarea de laborator Factory Method. Acolo, unul dintre grupurile de produsele concrete a fost CalculeStatistice. In cazul in care se doreste ca toate calculele sa se refere la acelasi vector de valori, se poate impune ca vectorul sa fie reprezentat printr-un obiect unic.
O posibilitate ar fi utilizarea variabilelor globale. Aceastea pot fi accesate de mai multi clienti, dar nu pot opri instantierea clasei respective de mai multe ori. Ca urmare, se impune o solutie prin care clasa insasi sa fie responsabila de crearea instantei unice si de oferirea accesului la ea. Aceasta solutie o constituie sablonul Singleton.

Motivatii

Sablonul Singleton se aplica in situatiile in care:

trebuie ca pentru o anumita clasa sa existe doar o singura instanta si aceasta trebuie sa fie accesibila clientilor dintr-un punct de acces cunoscut;
instanta unica a unei clase trebuie sa poata fi extinsa prin derivare, iar clientii sa poata utiliza instanta extinsa fara a-si modifica propriul cod..


Solutie

In figura de mai jos este data structura de clase care constituie sablonul Singleton:

Clientii pot accesa instanta clasei Singleton doar prin intermediul operatiei Instance.
 

Consecinte

Sablonul Singleton are urmatoarele avantaje:

controleaza accesul la instanta unica, deoarece clasa Singleton incapsuleaza propria instanta;
conduce la reducerea spatiului de nume, deoarece nu implica folosirea variabilelor globale;
permite detalierea operatiilor si a reprezentarilor. Clasa Singleton poate fi derivata si este usor sa se configureze o aplicatie cu o instanta a clasei derivate;
poate fi adaptat pentru a se crea nu doar o singura instanta, ci un numar oarecare fixat, pastrandu-se mereu controlul asupra acestui numar. Pentru aceasta este necesar sa se modifice doar operatia Instance;
asigura o flexibilitate mai mare decat daca s-ar utiliza metode statice. O alternativa la sablonul Singleton ar fi fost ca toate functiunile clasei Singleton sa fie realizate cu ajutorul unor metode statice (practic in acest caz am fi avut de a face cu 0 instante, nu cu una). Dezavantajele ar fi ca:
  • solutia nu poate fi adaptata pentru situatia in care dorim 'n' instante in loc de 1;
  • metodele statice nu pot fi virtuale, deci nu pot fi redefinite in subclase pentru a putea beneficia de polimorfism.
Implementare
Asigurarea unicitatii instantei. O posibilitate in acest sens este de a ascunde operatia care creaza instante (constructorii) in spatele unei metode statice care poate garanta numarul de instante create. Aceasta metoda are acces la o variabila care contine sau care refera instanta si are grija sa initializeze variabila respectiva inainte de a o returna clientilor.

Curs 9 Curs 11