Sunteți pe pagina 1din 22

8 abloane de proiectare (Design patterns)

n domeniul proiectrii software exist soluii reutilizabile pentru problemele ce apar mai des. Un ablon de proiectare nu este un element de proiectare aflat ntr-o form final, direct transformabil n cod, ci doar o soluie pentru o anumit problem, soluie care, n timp, s-a dovedit folositoare n situaii asemntoare. abloanele de proiectare orientate obiect conin clase, relaiile i interaciunile dintre ele. Clasele coninute nu sunt ntr-o form final, structurile acestora putndu-se extinde cu elementele specifice fiecrui proiect. Algoritmii nu sunt considerai ca fiind abloane de proiectare deoarece ei rezolv probleme de implementare. Folosirea abloanelor de proiectare poate duce la creterea att a vitezei de dezvoltare a software-ului, ct i a calitii acestuia, prin utilizarea unor soluii testate, care iau dovedit eficacitatea. Proiectarea software-ului presupune luarea unor decizii a cror corectitudine se dovedete mai trziu, la partea de implementare. Reutilizarea unor abloane de proiectare ajut la prevenirea unor probleme majore i mbuntete claritatea codului pentru programatorii i arhitecii familiari cu aceste abloane. Reutilizarea abloanelor de proiectare este diferit de reutilizarea codului. Reutilizarea abloanelor de proiectare este practic o reutilizare de idei i nu de componente. n domeniul transformrii celor mai utilizate abloane de proiectare n componente se vorbete de o rat de succes de dou treimi (Meyer i Arnout). Nu orice ablon software este un ablon de proiectare. abloanele de proiectare privesc doar uurarea muncii de proiectare a aplicaiilor software. De exemplu, mai exist n domeniul software aa numitele abloane arhitecturale (architectural patterns), ce descriu, aa cum le sugereaz i denumirea, soluiile unor probleme de arhitectur software. abloanele de proiectare pot fi grupate n mai multe categorii: abloane creaionale (creational patterns); o singleton; o builder (constructor); o metod factory; o clas abstract factory; o prototip; abloane structurale (structural patterns); o adaptor; o compozit; o facade; o proxy; abloane de comportament (behavioral patterns) o observer; o strategy; o command; o iterator; o memento; o visitor; o mediator; o lan de responsabiliti (chain of responsability) Pentru exemplificare vom crea n NetBeans dou proiecte: un proiect UML Java platform Model i un proiect Java Desktop Application. Pentru o mai bun organizare a
1

claselor vom crea n ambele proiecte pachetele surs: sabloane_creationale, sabloane_structurale i sabloane_comportamentale. n proiectul UML crem o diagram de clase i dm n spaiul alb al acesteia click dreapta i Apply Design Pattern.... Dac un ablon nu presupune prea multe clase i dorim s introducem ablonul direct n model fr s l vizualizm ntr-o clas de diagrame putem da click dreapta pe nodul Model i vom gsi aceeai opiune Apply Design Pattern.... Wizardul ce ese deschide ne d posibilitatea s introducem din proiectul GoF Design Patterns n propriul proiect UML principalele abloane de proiectare din literatura de specialitate (GoF vine de la Gang of Four, autorii Design Patterns: Elements of Reusable Object-Oriented Software, o carte de referin n literatura de specialitate). Clasele proiectului UML pot fi generate automat n proiectul Java de la opiunea Generate Code (click dreapta pe clasa UML).

8.1 abloane creaionale


abloanele creaionale sunt utilizate de obicei pentru a separa crearea obiectelor de utilizarea lor. Scopul principal al unui astfel de demers este de a permite introducerea n sistem a noilor tipuri derivate fr a fi necesare schimbri asupra codului ce folosete clasele de baz.

8.1.1 ablonul Singleton


Singleton este un ablon folosit pentru a restriciona instanierea unei clase la un singur obiect. Acest concept este uneori generalizat pentru a restriciona instanierea la un anumit numr de obiecte. ablonul singleton se implementeaz prin crearea unei singure clase ce conine o asociere reflexiv (unul din propriile atribute este tot de tipul clasei). Elementul cheie al acestui ablon este faptul c atributul ce are chiar tipul clasei este de tip static. Modificatorul static folosit la declararea unui atribut sau la declararea unei metode arat apartenena membrului respectiv la clas i nu la o instan a ei (la un obiect). n cazul unui atribut static, ca n exemplul ablonului singleton, se aloc memorie o singur dat, la prima initializare a clasei. La urmatoarele instanieri ale clasei nu se mai aloc memorie pentru un atribut static, dar toate obiectele din acea clas pot accesa aceeai variabil static, aflat n aceeai zon de memorie. Pe lng cele specificate mai sus, o clas singleton mai poate conine atribute i operaii specifice domeniului n care este utilizat. ablonul singleton prevede i existena unui constructor privat (dar acest constructor nu este definit i n ablonul prestabilit din NetBeans). Dac acest constructor nu ar fi privat clasa ar putea fi instaniat de mai multe ori i nu ar mai iei un singleton. Neexistnd constructorul, instana unic se obine cu o metod static denumit n continuare instance( ) (tot un fel de metod get). Aceast metod fiind static poate fi apelat cu sintaxa:
Obiect_returnat = clas.metod_static();

i ea ne va returna ntotdeuna obiectul unic instaniat (atributul static de acelai tip cu clasa n care este inclus).

Fig. 8.1 Reprezentarea unei clase singleton Instana unic poate fi creat: 1) implicit la definirea acestui element (o instaniere nu tocmai lene, mai degrab grbit i risipitoare), caz n care metoda instance( ) trebuie doar s returneze o referin la acest obiect:
public static Singleton instance() { return uniqueInstance; }

2) explicit n metoda static instance( ), dac o astfel de instan nu exist deja (aceast modalitate de instaniere este denumit instaniere lene).
public static Singleton instance () { if(uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; }

Putem testa ablonul astfel creat folosindul la crearea a dou obiecte: marie i aceeasiMarie.
private sabloane_creationale.Singleton marie; private sabloane_creationale.Singleton aceeasiMarie; marie = sabloane_creationale.Singleton.instance(); marie.setSingletonData(3); String s = new Integer(marie.getSingletonData()).toString(); System.out.println("Atributul singletonData primeste valoarea " + s); aceeasiMarie = sabloane_creationale.Singleton.instance(); String s = new Integer(aceeasiMarie.getSingletonData()).toString(); System.out.println("Atributul singletonData avea deja valoarea " + s);

La lansarea codului de mai sus descoperim c, indiferent de ceea ce se spune aceeasiMarie are aceeai plarie (pardon ... aceeai valoare a atributului singletonData) i asta pentru c este tot o referin ctre acelai obiect uniqueInstance. Exemple de utilizare a ablonului singleton: - clasa user ntr-o aplicaie n care se dorete gestiunea unitar a drepturilor unui utilizator logat;
3

clasa destinat conexiunii cu baza de date atunci cnd se dorete ca aplicaia s foloseasc la un moment dat o singur baz de date. Pot exista i versiuni ale ablonului singleton, cele n care se limiteaz instanierea ale unei clase nu doar o instan. De exemplu, ntr-un joc de ah clasa juctor ar trebui s fie instaniat numai de dou ori. Soluia n acest caz presupune: - un constructor privat; - dou atribute statice de tipul clasei (uniqueWhite i uniqueBlack); - dou metode statice care s returneze cele dou instane unice (getUniqueWhite i getUniqueBlack). -

Fig. 8.2 Clasa singleton Player ntr-un joc de ah Metodele statice din acest exemplu ar trebui s se asigure mai nti c exist instanele statice corespunztoare i apoi s le iniializeze, adic s le dea o nuan de alb sau de negru:
public Player getUniqueWhite() { if (uniqueWhite == null) { uniqueWhite = new Player(); color = "White"; } return uniqueWhite; }

Observaie: n exemplul de mai sus nici nu este nevoie de o operaie setColor, deoarece culoarea este stabilit doar la instanierea juctorului i nemodificat pe parcursul jocului. NetBeans ne d posibiliatea s crem propriile abloane de proiectare pe lng cele prestabilite folosind opiunea Window\Other\UML Design Center. Aici putem crea un nou proiect cu abloane, denumit eventual MyPatterns. n acest proiect putem specifica propriul singleton crend urmtoarea diagram de clase:

Fig. 8.3 Diagrama de clase necesar crerii propriului singleton


4

8.1.2 Metod factory


Termenul factory (fabric) este utilizat n acest context pentru a arta locul destinat construirii de obiecte. ablonul metod factory presupune crearea unei clase de baz (Creator) ce conine o metod destinat crerii obiectelor de un anumit tip (factoryMethod).

Fig. 8.4 ablonul metod factory Subclase ale clasei factory pot suprascrie metoda factory pentru a se specifica anumite subtipuri ale obiectelor obinute. ablonul este folosit n ierarhiile de clase paralele, cnd obiectele dintr-o ierarhie creeaz obiecte corespunztoare din cealalt ierarhie. Acest ablon poate fi implementat cu dificultate atunci cnd este folosit pentru clase ce au deja clieni.

8.1.3 Clas abstract factory


ablonul abstract factory asigur o modalitate de grupare a mai multor metode factory ce au elemente comune. Conform acestui ablon se creeaz o clas abstract factory ce va sta la baza mai multor clase concrete factory. Clasele factory conin cte o metod factory pentru fiecare tip de obiect ce trebuie creat. Codul client lucreaz doar cu tipul abstract de factory, nedepinznd de tipurile concrete. Conform acestui ablon, sunt create obiect concrete, dar codul client le acceseaz doar prin interfaa lor abstract. Adugarea de noi tipuri concrete sistemului se face prin modificarea codului client n aa fel nct s foloseasc o nou clas concret factory.

Fig. 8.4 ablonul clas abstract factory

8.1.4 Prototip
ablonul const n folosirea unei instane drept prototip pentru crearea (clonarea) de noi obiecte. ablonul protoype este folosit pentru: - a evita folosirea subclaselor concrete factory n aplicaiile client; - a evita crearea de obiecte n mod clasic, cu metode constructor. Pentru implementarea acestui ablon se declar o clas de baz abstract ce specific o operaie clonePrototype. Orice clas ce are nevoie de un constructor polimorfic va deriva din clasa de baz abstract i implementeaz operaia clonePrototype.

Fig. 8.5 ablonul prototip

8.1.5 Builder
ablonul builder ajut la abstractizarea pailor construirii unor obiecte, altfel spus a reetelor de fabricaie. Obiectele de obinut nu fac parte dintr-o anumit ierarhie de clase, dar exist constrngerea ca valorile atributelor acestora s nu aib sens dect ntr-o anumit
6

combinaie. Fiecare combinaie de valori ale atributelor se obine cu un anumit builder (cu o anumit reet de fabricaie). Aceti builder-i sunt organizai ntr-o ierarhie de clase.

Fig. 8.6 ablonul builder Clasa director este cea care construiete efectiv produsul cu ajutorul unui builder (reete de fabricaie) pe care l conine. Metoda construct din clasa director include o secven de apelri a metodelor de construire a prilor (atributelor) produselor. Cum toate produsele (obiectele) obinute sunt instane ale aceeleiai clase nseamn c toate au aceleai pri i prin urmare toate se pot obine prin respectarea aceleiai secvene de construire. Pot exista variante ale acestui ablon n care Builder este o clas abstract i nu o interfa. Motivul folosirii unei clase abstracte poate fi n acest caz agregarea n Builder a unui obiect produs protejat (protected). Cel mai reuit exemplu de utilizare a ablonului builder este cel de pe wikipedia unde clasei cu rolul product este clasa pizza, clasele cu rolurile concretebuilder sunt diferitele reete de pizza, iar clasa cu rolul director este clasa.

8.2 abloane structurale


8.2.1 Adaptor
Adaptorul (cunoscut i sub numele de wrapper) este o clas ce permite traducerea unor interfee n alte interfee. Adaptorul permite unor clase cu interfee incompatibile s interacioneze. Acest ablon este folositor atunci cnd o clas deja implementat (clasa de adaptat sau clasa furnizor) asigur funcionalitile dorite, dar nu i interfaa dorit. Adaptorul tie s rspund cel puin la interfaa dorit de client, din acest motiv clasa adaptor este utilizat n mod direct de ctre clasa client. n acelai timp adaptorul tie s utilizeze funcionalitile clasei de adaptat. n acest fel, clasa client este independent de structura interfeei de adaptat. Cu un astfel de ablon clasa client poate modifica furnizorii de funcionaliti fr s i modifice propria structur, doar utiliznd ali adaptori.

Exist dou tipuri de adaptoare, n funcie de modul n care adaptorul reuete s utilizeze funcionalitile clasei de adaptat: 1. adaptoare ce implementeaz interfaa dorit de client i care conin n plus o instan a clasei de adaptat = object adapter;

Fig. 8.7 ablonul object adapter n metoda request a adaptorului se scrie n acest caz:
public void request () { furnizor.specificRequest(); }

2. adaptoare care implementeaz ambele interfee i care n metodele ce implementeaz operaiile interfeei dorite se face trimitere la operaiile interfeei de adaptat = class adapter. n acest caz se poate vorbi de o adaptare bidirecional a claselor.

Fig. 8.8 ablonul class adapter cu implementare multipl de interfee

Adaptorul descris n figura 8.8 poate fi folosit att pentru o aplicaie ce depinde de ClassA, dar care dispune de ClassB, ct i invers. ablonul class adapter presupune folosirea motenirii multiple, de unde i vin i anumite dezavantaje: - nu toate mediile de programare suport complet motenirea multipl (de aceea figura 8.8 face referire la implementrile a dou interfee i nu la extinderea a dou clase); - pot apare conflicte ntre operaiile celor dou interfee cnd aceste operaii au aceeai semntur dar o semantic diferit Un exemplu de utilizare a ablonului object adaptor este cel n care aplicaiile client de messenger pot utiliza diferite servere de messenger. Iniial un client de messenger poate fi dezvoltat pentru un singur server, ulterior dorindu-se utilizarea i a altor servere. Figura 8.9 face referire la clasele specifice unei astfel de aplicaii iniiale n care clientul, n metoda sendText, utilizeaz metoda sendText dintr-un anumit server.

Fig. 8.9 Diagrama claselor ntr-o aplicaie de messenger Pentru utilizarea unui alt server de messenger, clasa ServerMessenger se poate specializa ntr-un adaptor ce conine ca i membru un obiect de tipul unui alt server. Metoda sendText a adaptorului suprascrie metoda sendText a serverului iniial fcnd delegnd activitatea de realizat membrului obiect de tipul celuilalt server, mai exact folosind metoda sendMessage a acestuia.

Fig. 8.10 Aplicaie de messenger cu un object adapter


9

Alte exemple de utilizare a adaptoarelor: - wrapper-ele din bazele de date federative (DB2) care fac legtur ntre baze de date eterogene; - comenzile de aprovizionare ce pot fi transmise direct furnizorilor ntr-un mediu B2B; - coletele de transmis prin intermediul oficiilor potale diferite.

8.2.2 Compozit
ablonul compozit permite unui grup de obiecte s fie tratat ca un singur obiect. Cu ajutorul acestui ablon o operaie specific elementelor componente poate fi lansat i pentru un agregat, situaie n care operaia se lanseaz pentru toate elementele agregate. Una din situaiile n care ablonul compozit se face util este cea n care se gestioneaz structuri ierarhice. Diferena structural dintre noduri i frunze face ca lucrul cu structuri ierarhice s fie complex. Soluia propus de ablon este de a obine elementul compozit (nodul n cazul structurilor ierarhice) din specializarea clasei destinat componentelor (frunzelor).

Fig. 8.11 ablonul compozit ablonul nu este util doar n cazul structurilor ierarhice, ci n toate relaiile de compunere n care operaiile unui grup de obiecte include operaiile unui singur obiect. Clasa destinat componentelor conine pe lng implementarea operaiilor specifice domeniului afacerii i declararea interfeei pentru accesarea i gestiunea componentelor copil (adugare, tergere, citire etc.). Clasa compozit implementeaz metodele de manipulare a componentelor copil, iar n cazul operaiilor specifice domeniului afacerii i deleg sarcinile operaiilor corespunztoare ale obiectelor copil. n exemplul urmtor este vorba de ziariti care fac parte din redacii, redacii care aparin de anumite publicaii (ziare, reviste etc.), publicaii ce aparin unor trusturi de pres. ablonul compozit ne ajut n acest caz ca o operaie specific unui ziarist (cea de a ataca) s fie lansat (de un mogul) pentru un ntreg trust, cu un efort minim, fr a apela fiecare ziarist n parte, ci apelnd doar operaia ataca a obiectului trust.
10

Fig. 8.11 ablonul compozit


public interface Componenta { public void ataca (); } public class Ziarist implements Componenta { public void ataca () { System.out.println("Hau hau!"); } } public class Grup implements Componenta { private ArrayList<Componenta> mComponenta = new ArrayList<Componenta>(); public void ataca () { for (Componenta componenta : mComponenta) { componenta.ataca(); } } public void add (Componenta c) { mComponenta.add(c); } public void remove (Componenta c) { mComponenta.remove(c); } }

Dac declaraiile de mai sus ar face parte din pachetul sabloane_structurale, intrnd n pielea unui mogul am putea utiliza codul urmtor:
sabloane_structurale.Grup trust = new sabloane_structurale.Grup(); sabloane_structurale.Grup ziar = new sabloane_structurale.Grup(); sabloane_structurale.Grup redactie = new sabloane_structurale.Grup(); sabloane_structurale.Ziarist popescu = new sabloane_structurale.Ziarist(); sabloane_structurale.Ziarist ionescu = new sabloane_structurale.Ziarist(); sabloane_structurale.Ziarist altescu = new sabloane_structurale.Ziarist(); redactie.add(popescu); redactie.add(ionescu);

11

redactie.add(altescu); ziar.add(redactie); trust.add(ziar); trust.ataca();

8.2.3 Facade (faad)


O faad este un obiect ce asigur o interfa simplificat spre un grup de clase. Cu ajutorul acestui ablon o bibliotec software devine mai uor de neles i de utilizat, reducndui dependena de restul codului (scade cuplarea). O faad este recomandat i atunci cnd trebuie s folosim o colecie de clase ce folosesc interfee prost proiectate sau greu de neles, n sperana c interfaa faadei va rezolva aceste probleme.

Fig. 8.12 ablonul facade


12

n exemplul din figura 8.12 cel care creaz obiectele de tip tranzacie (dintr-o interfa utilizator sau dintr-o procedur de import) nu trebuie s cunoasc detaliile claselor de contabilitate i gestiune, ci doar c o tranzacie, o dat creat, trebuie transmis faadei ContabilitateSiGestiune pentru nregistrarea acesteia n contabilitate i afectarea gestiunilor corespondente. n acest caz metoda contabilizeaza din faada ContabilitateSiGestiune include toat secvena de apelri a claselor: RegistruJurnal, CarteaMare, RegistruDeCasa, RegistruDeBanca, Stocuri.

8.2.4 Proxy
La modul general un proxy este o resurs (clas, server etc.) care funcioneaz ca o interfa pentru altceva. Un proxy nu face dect s delege aciunile mai departe unei alte clase.

Fig. 8.13 ablonul proxy Exist patru situaii n care se recomand s folosim un astfel de ablon: 1) Virtual proxy = o clas de acces ctre obiectele unei alte clase ce presupunhe utilizarea multor resurse; obiectul real este creat la prima cerere de acces la acesta. 2) Remote proxy = asigur o reprezentare local pentru un obiect dintr-un spaiu diferit de memorie; n RPC i CORBA o astfel de funcionalitatea o asigur un stub. 3) Protective proxy = clas de control al accesului la obiecte mai sensibile din punct de vedere al securitii. Obiectul proxy verific dac expeditorul are dreptul s transmit mesaje destinatarului. 4) Smart proxy = clas care nu doar transmite mai departe o operaie de realizat, ci realizeaz n plus o serie de aciuni, cum ar fi: a. numr referirile la un anumit obiect; b. ncarc obiecte persistente la prima utilizare; c. verific dac obiectul adevrat este blocat pentru alte accese (asigur prelucrri tranzacionale i diferite niveluri de izolare)

13

8.3 abloane comportamentale


8.3.1 Mediator
De obicei o aplicaie este alctuit dintr-un numr important de clase. Cu ct sunt mai multe clase ntr-o aplicaie, problema comunicrii ntre obiecte devine mai complex, ceea ce face programul mai greu de citit i ntreinut. Modificarea programelor, n astfel de situaii, devine mai dificil din moment ce orice modificare poate afecta codul din mai multe clase. Cu ajutorul ablonului mediator comunicaia dintre obiecte este ncapsulat n obiectul mediator. Obiectele nu mai comunic direct ntre ele, ci comunic n schimb prin intermediul mediatorului. Acest lucru reduce dependena ntre obiecte, micornd cuplarea. n contextul acestei diagrame termenul de coleg este utilizat pentru a desemna un obiect ce dorete s comunice cu alte obiecte din acelai grup, un grup avnd un singur moderator.

Fig. 8.14 ablonul mediator Mediator - definete interfaa de comunicare ntre obiecte ConcreteMediator - implementeaz interfaa Mediator i coordoneaz comunicarea ntre objecte. tie care sunt toate obiectele ce doresc s comunice i scopurile acestor comunicri. ConcreteColleague comunic cu alte obiecte colegi cu ajutorul mediatorului. ablonul mediator se poate combina cu ablonul singleton, dac o clas concret mediator are sens s fie instaniat o singur data. ntr-un astfel de caz, dac aplicaia abstractizeaz mai multe grupuri de colegi, pentru fiecare grup se poate crea cte o clas concret mediator care s fie instaniat o singur dat. ablonul mediator nu trebuie confundat cu ablonul proxy. Diferena principal este faptul c mediatorii i colegii nu sunt creai pe baza aceleiai interfee (sau clase abstracte). Un proxy este imaginea unui alt obiect, prin urmare structura unui proxy depinde destul de mult de structura obiectului destinaie. Nu degeaba ablonul proxy este inclus n grupul abloanelor structurale. Structura unui mediator nu este imaginea n oglind a unui obiect coleg, ceea ce i d posibilitatea s transmit mesajele spre mai multe tipuri de clase concrete de colegi, altfel spus s medieze mesajele ntre colegi cu structuri diferite. Exist asemnri ntre ablonul mediator i alte abloane la lista de avantaje: un coleg (binevoitor) poate s transmit anonime (avantaj ntlnit i la proxy);
14

un coleg (rspndac) poate s transmit acelai mesaj mai multor obiecte (avantaj ntlnit i la ablonul compozit); un mediator (securist) poate s foloseasc liste de control al accesului (avantaj ntlnit i la proxy); un mediator (mai lene) poate atepta mai multe mesaje de la colegi pentru a lansa o anumit operaiune (avantaj specific ablonului mediator). Exemplu de folosire a ablonului moderator: organizarea unor vizite (de exemplu la Moscova) poate fi realizat prin intermediul unui moderator (de exemplu ambasadorul rus la Bucureti). Utiliznd terminologia acestui ablon, colegi sunt persoanele ce urmeaz s se ntlneasc. Din pcate, ablonul mediator nu reflect i relaii de subordonare ntre colegi. Un alt exemplu (total rupt de cel anterior) este cel al unei reele de spionaj n care colegi sunt spionii i persoanele decidente din structurile de informaii. Mediatorii n acest exemplu sunt persoanele de legtur, care fac ca de cele mai multe ori colegii s nu se cunoasc ntre ei.

8.3.2 Observator
ablonul observator este un ablon de proiectare n care un obiect gestioneaz o list cu proprii dependeni, pe care i anun automat de eventualele modificri de stare, de obicei prin apelarea anumitor metode. De multe ori acest ablon este folosit pentru implementarea sistemelor distribuite.

Fig. 8.15 ablonul observator Clasa Subject este o clas abstract (sau o interfa) ce asigur ataarea i scoaterea observatorilor. Clasa conine pe lng o list privat cu observatori i urmtoarele metode: attach( ) adaug un nou observator n list;
15

detach( ) elimin un observator din list; notifyObserver( ) anunt fiecare observator asupra unei schimbri de stare prin apelarea metodelor update( ) ale acestora. Clasa ConcreteSubject este elementul de interes al observatorilor. Ea trimite o notificare tuturor observatorilor prin apelarea metodei notifyObserver( ) din clasa ei printe. Clasa ConcreteSubject conine pe lng interfaa Subject metoda GetState ce returneaz starea subiectului de observat. Clasa Observer definete o interfa pentru anunarea tuturor observatorilor asupra modificrilor survenite n subiect. Interfaa const ntr-o metod ce va fi suprascris de fiecare observator concret. Clasa ConcreteObserver gestioneaz o referin ctre clasa ConcreteSubject i conine operaia update( ). Cnd acest operaie este apelat de ctre subiect, ConcreteObserver apeleaz operaia GetState a subiectului pentru a-i actualiza informai privind starea subiectului. Operaia update( ) poate primi eventual parametri cu informaii generale ale evenimentului aprut, informaii utile observatorului. ablonul observator este utilizat atunci cnd modificarea strii unui obiect afecteaz alte obiecte i nu se tie la momentul scrierii codului exact ce obiecte vor trebui anunate. Exemplu de folosire a ablonului observer: implementrarea modurilor de lucru, cnd ntr-o fereastr de dialog utilizarea unui obiect poate presupune disponibilizarea sau indisponibilizarea altor obiecte. n terminologia acestui ablon toate obiectele de pe un formular sunt observatori, iar subiectul concret de observat este chiar formularul. Fiecare obiect n parte nu trebuie s modifice direct celelalte obiecte de pe formular pentru c ar trebui s cunoasc mulimea acestora. Aceeai funcionalitate a modurilor de lucru ar putrea fi implementat i cu ajutorul ablonului mediator.

8.3.3 Lan de responsabiliti


ablonul lanului de responsabiliti (chain of responsibility) este un ablon comportamental care permite evitarea cuplrii directe a expeditorului unei cereri cu un anumit destinatar, folosindu-se n acest sens clase intermediare. Avantajele unui astfel de ablon: - expeditorul poate s nu cunoasc exact care este destinatarul final al cererii sale, pe el interesndu-l doar ca respectiva sarcin s fie ndeplinit; - clasele intermediare pot alege destinatarii, gestionnd eventual i gradul de solicitare al acestora i gradul de solicitare a sistemelor de calcul pe care ruleaz acetia; - o cerere poate fi procesat de mai muli destinatari, n acelai timp, secvenial sau respectnd chiar anumite fluxuri de cereri; - clasele intermediare pot realiza log-uri ale cererilor; - lipsa oricrui potential destinatar poate fi aflat de ctre expeditor printr-un mesaj primit de la clasele intermediare.

16

Fig. 8.16 ablonul lan de responsabiliti Un exemplu de astfel de ablon este modul de autorizare a unor tranzacii de ctre anumii angajai n funcie de mrimea acestor tranzacii. Aprobarea unui credit poate fi fcut la nivelul unui ofier de credit, manager al departamentului de credite, ef de filial sau sucursal i n rare cazuri un credit are nevoie i de aprobarea managerilor din central. Pentru fiecare rol mentionat mai sus se creaz o clas Functie (cu rolul de ConcreteHandler), n care exist un atribut ce ne indic limita creditului ce poate fi aprobat fr a fi trimis i la nivelul ierarhic superior.

Fig. 8.17 Exemplu de utilizare a ablonului lan de responsabiliti Fiecare clas Funcie va implementa metoda proceseazDosarCredit, n mod asemntor cu codul urmtor:
public void proceseazaDosarCredit( Credit c ) { if ( c.suma <= limitaCredit ) { //proceseaz efectiv dosarul n sensul aprobrii sau respingerii lui } else if ( superior != null ) superior. proceseazaDosarCredit(c); }

E ca un fel de aruncarea mei moarte n ograda vecinului n funcie de starea de putrefacie a bietului animal. Cu ct starea de putrefacie este mai mare cu att pisica va ajunge la un vecin mai ndeprtat (n sperana c toi vecinii vor pstra aceeai direcie).
17

8.3.4 Memento (Amintire)


ablonul amintire (memento) este un ablon comportamental destinat salvrii diferitelor stri curente ale unor obiecte i revenirea la aceste stri. n acest ablon se folosete o clas de amintire (Memento) ce conine aceleai proprieti de stare ca i clasa obiectelor de salvat (Originator). Obiectele de amintire se pot gestiona eventual ntr-o colecie (Caretaker). Obiectul de salvat trebuie s conin cte o metod pentru fiecare din aceste dou aciuni: salvare (createMemento) i revenire la stare anterioar (setMemento).

Fig. 8.18 ablonul memento Clientul care ar folosi un astfel de ablon ar ncepe prin utilizarea metodei createMemento din Originator, iar obiectul memento astfel obinut ar fi folosit ca parametru de intrare n metoda addMemento din Caretaker:
caretaker.addMemento(originator.createMemento());

Revenirea la o stare anterioar, n condiiile n care se tie un anumit numr de ordine al acesteia n cadrul coleciei de stri:
originator.setMemento(caretaker.getMemento(7));

8.3.5 Strategie
ablonul strategie ne ajut s alegem un anumit algoritm de utilizat n funcie de un context. ablonul conine un grup de algoritmi, fiecare din acetia fiind ncapsulat ntr-un obiect. Clienii ce folosesc algoritmii nu depind de acetia, variind n mod independent.

18

Fig. 8.19 ablonul strategie Obiectele de tip context conin cte un obiect strategy, dar alegerea unei strategii concrete se realizeaz n funcie de context. Conform ablonului strategy comportamentul unei clase nu ar trebui s fie motenit, ci specific contextului n care ruleaz.

8.3.6 ablonul iterator


ablonul iterator este folosit pentru a accesa elementele unui agregat (a unei colecii) n mod secvenial, fr a ne folosi de caracteristicile acestor elemente. In orice moment unul din elementele coleciei este considerat ca fiind elementul curent.

Fig. 8.20 ablonul iterator


19

Operaii ale elementelor coleciei de parcurs ar putea fi: - currentItem (ghici ce face fiecare operaie); - first; - last; - next; - previous; - hasNext; - hasPrevious; - isFirst; - isLast. ablonul iterator are un grad mai mare de importan n mediile de dezvoltare n care nu sunt implementate complet tipuri de date compuse (vectori, liste, stive).

8.3.7 ablonul interpreter


ablonul interpreter descrie cum se pot interpreta expresiile ntr-un anumit limbaj. El i gsete utilitatea n aplicaiile economice n care se dorete salvarea unor formule de calcul ntr-un format accesibil utilizatorilor finali i folosirea ulterioar de ctre aplicaie a acestor formule. Conform ablonului interpreter att operanzii, ct i operatorii dintr-o expresie ar trebui s aib aceeai interfa.

Fig. 8.20 ablonul interpreter Diagrama claselor de mai sus (cea din NetBeans de la acest ablon) nu surprinde nevoia existenei unui evaluator de expresii. Acest evaluator trebuie s mpart expresia de interpretat n mai multe pri cu un parser. Tot evaluatorul trebuie s parcurg fiecare parte a expresiei: - cnd ntlnete un operand (o variabil pe care are voie utilizatorul s o foloseasc ntr-o anumit formul) l introduce ntr-o stiv; - cnd ntlnete un operator extrage din stiv valorile operanzilor afectai i introduce n loc rezultatul aplicrii operatorului asupra operanzilor. Dac se pleac de la o expresie corect la sfritul parcurgerii acesteia n stiva utilizat va rmne o singur valoare, ea fiind chiar rezultatul interpretrii.
20

Exemple de aplicaii n care ar putea fi utilizat ablonul interpreter: - aplicaii de salarizare; - aplicaii de procesare a datelor la importul sau exportul lor din diferite sisteme; - aplicaii de interpretare a unui dialect SQL sau de traducere dintr-un dialect SQL n altul. Un interpretor poate fi vzut i ca o cutie neagr creia i se d o expresie i care returneaz un rezultat. Cum nu trebuie s reinventm roata putem folosi interpretore deja existente, cum ar fi cele pentru scripturi:
import javax.script.ScriptEngineManager; import javax.script.ScriptEngine; ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine jsEngine = mgr.getEngineByName("JavaScript"); try { Object result = jsEngine.eval("Expresia JavaScript de evaluat!"); } catch (ScriptException ex) { // tratarea excetiilor }

8.3.8 ablonul command


Conform ablonului command un obiect poate ncapsula toate informaiile necesare pentru apelarea unei metode a altui obiect, cum ar fi: numele metodei de apelat, obiectul ce deine metoda i valorile de transmis parametrilor.

Fig. 8.21 ablonul command Clientul instaniaz obiectul de tip comand i l pregtete pentru a fi apelat la un moment ulterior. Obiectul invoker decide cnd va fi apelat obiectul comand. Obiectul receiver este cel care va efectua o aciune ca urmare a lansrii n execuie a comenzii. Beneficiile acestui ablon in de faptul c execuia unei anumite metode poate fi pregtit din timp, n aa fel nct aceasta s fie lansat fr s i se tie numele, obiectul de care aparine i momentul exact al execuiei. ablonul command poate fi utilizat pentru a realiza aplicaii cu:
21

- funcionaliti de tip undo; - comportament tranzacional; - progress bar sincronizat cu execuia unui grup de comenzi; - funcionaliti de tip wizard; - nregistrri de macro-uri; De exemplu, dac un ppuar (client) dorete s pun o ppu (receiver) s se bucure (concretecommand) folosete un invoker, iar acesta i transmite ppuii s opie (metoda action din ablon).

22