44
Design Patterns TEMA – INGINERIE SOFTWARE Studenți: Mihai Octavian 441A Diaconescu Radu 441A Sălăjan Alexandru 441A Universitatea Politehnica București Facultatea de Electronică, Telecomunicații și Tehnologia Informației București - 2015

Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

  • Upload
    others

  • View
    13

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

Design Patterns TEMA – INGINERIE SOFTWARE

Studenți: Mihai Octavian 441A

Diaconescu Radu 441A

Sălăjan Alexandru 441A

Universitatea Politehnica București

Facultatea de Electronică, Telecomunicații și Tehnologia Informației

București - 2015

Page 2: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

1

Curpins:

1. Introducere……………………………………………………………………………..2

2. Creational Patterns (Salajan Alexandru) ...…………………….………..3

2.1 Abstract factory pattern………………………………………….…………3

2.2 Factory Method pattern……………………………………….……………8

2.3 Prototype pattern…………………………………………………………….10

2.4 Singleton pattern……………………………………………………………..13

3. Behavioral patterns (Diaconescu Radu) …………………….…………..14

3.1 Introducere……………………………………………………….……………..15

3.2 Strategy pattern……………………………………………………………….15

3.3 Template Method pattern………………………………………………..18

3.4 Iterator pattern ………………………………………………………….…….21

3.5 Command pattern…………………………………………….………………24

4. Structural Patterns (Mihai Octavian) ……………………….……………..28

4.1 Adapter pattern………………………………………………..….……………29

4.2 Bridge Design pattern……………………………………..….……………..33

4.3 Composite pattern…………………………………………………………….36

4.4 Decorator pattern……………………………………………………………..40

5. Bibliografie…………………………………………………………..………………….43

Page 3: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

2

1.Introducere:

În ingineria software, un model de design (design pattern) reprezintă o soluție a unei probleme

ce apare de obicei apare în design-ul de software, ce poate fi reutilizabilă în mod general. Un model de

design nu este neapărat un design ce poate fi implementat direct în cod. El reprezintă o descriere sau un

șablon pentru modul de a rezolva o problem, permițând folosirea sa în mai multe situații diferite.

Modele de design obiect orientate referă de obicei relațiile și interacțiunile dintre clase sau obiecte, fără

a specifica clasele de aplicații finale sau obiectele care sunt implicate.

Modele de design se regăsesc în module și interconexiuni. La un nivel mai ridicat există însă

modele arhitecturale ce sunt caracterizate de prezența lor în domeniul de aplicare, de obicei, acestea

descriind un model global, urmat de un întreg sistem.

Există mai multe tipuri ale acestor modele de design: Structural patterns(modelul structural) ce

răspund de preocupările legate de structura la nivel înalt a unei aplicații în curs de dezvoltare. Un

behavioral pattern(model comportamental) explică modul în care obiectele interacționează.

Acesta descrie modul în care diferite obiecte și clase trimit mesaje unul altuia pentru a face

lucrurile să se întâmple și cum etapele unei sarcini sunt împărțite între diferite obiecte.

Împărțirea etapelor se face prin folosirea moștenirii. Creational patterns (modelele creationale)

se referă în general la instanțierea claselor și pot fi împărțite în modele de creare a

claselor(class-creation patterns) și modele de creare a obiectelor(object-creational patterns) .

Model-ul de creare a claselor folosește moștenirea în procesul de instanțiere, iar model-ul de

creare a obiectelor va delega instanțierea unui alt obiect.

Modele de proiectare pot accelera procesul de dezvoltare prin furnizarea de cunoștințe

și ipoteze testate și acceptate. Proiectarea eficienta a unui software necesită acoperirea tutor

problemelor, chiar și a celor ce pot deveni vizibile în etape mai târzii de dezvoltare a aplicației.

Reutilizarea modelelor de design ajută la prevenirea problemelor subtile care se pot transforma

în majore și îmbunătățesc citirea codului pentru programatori și arhitecții familiarizați cu

modelele de design.

De multe ori, oamenii înțeleg doar cum se aplică anumite tehnici de proiectare a

software-ului pentru o arie restrânsa de probleme. Aceste tehnici sunt însă dificile de aplicat la

o gamă mai largă de probleme. Modelele de design oferă soluții generale, documentate într-un

format, ce nu are nevoie sa se specifice o problemă particulară.

Modelele de design au ca și origine un concept arhitectural pus in aplicare de

Christopher Alexander(1977-1979). În anul 1987, Kent Beck și Ward Cunningham au început să

experimenteze cu această idee. Rezultat-ul a constat în aplicarea modelelor de design și

prezentarea rezultatelor la conferința OOPSLA în acel an. În anii următori, Beck, Cunningham și

alții au urmat acest drum.

Page 4: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

3

Modelele de design software au câștigat popularitate în industria software după ce

cartea „Design Patterns: Elements of Reusable Object-Oriented Software” a fost publicată în

anul 1994 de așa numiții “Gang of Four” (Grupul celor Patru - Erich Gamma, Richard Helm,

Ralph Johnson și John Vlissides ). În același an, prima conferință ce a tratat aceste modele de

design a avut loc, iar în anul următor a fost lansat “Portland Pattern Repository”, ce punea la

dispoziție toată documentația necesară folosirii modelelor de design software.

2.Creational Patterns

Modelele creationale(Creational patterns) se refera in general la instantierea claselor si

pot fi impartite in modele de creare a claselor(class-creation patterns) si modele de creare a

obiectelor(object-creational patterns) . Modelelul de creare a claselor foloseste mostenirea in

procesul de instantiere , modelelul de creare a obiectelor va delega instantierea unui alt obiect.

Modelele creationale devin importante pe masura ce sistemul evolueaza pentru a

depinde mai mult de compozitia obiectului decat de clasa mostenita .

Modelele creationale sunt :

Abstract Factory: Creeaza o instanta de mai multe familii de clase .

Builder: Separa constructia obiectului de reprezentarea lui .

Factory Method: Creeaza o instanta de mai multe clase derivate .

Object Pool: Evita achizitiile costisitoare si elibereaza resursele prin reciclarea

obiectelor care nu mai sunt utilizate.

Prototype: O instanta complet initializata pentru a fi copiata sau clonata.

Singleton: O clasa in care poate exista numai o instanta .

2.1.Abstract Factory Design Pattern

Atribute:

Asigura o interfata pentru crearea familiilor de obiecte de

acelasi tip sau obiecte dependente fara a specifica concret

clasele lor .

O ierarhie care incapsuleaza mai multe platforme posibile,

precum si constructia unui set de produse .

Noul operator e considerat daunator.

Page 5: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

4

Fig.1 –Diagrama UML reprezentând un model de implementare pentru Abstract Factory Design Pattern

(http://sourcemaking.com/files/v2/content/patterns/Abstract_Factory_example1-2x.png)

Problema design-ului: daca o aplicatie este portabila , trebuie incapsulate dependentele

platformei. Aceste platforme pot include : sistemul de operare, baza de date , etc . De cele mai

multe ori, aceasta incapsulare nu este proiectata in avans, si o multime de declaratii de caz

(#ifdef) cu optiuni pentru toate platformele suportate in prezent incep sa se inmulteasca

extrem de repede in intregul cod.

Structura:

Modelul „Abstract Factory” defineste un model „Factory Method” pentru fiecare

produs. Fiecare model „Factory Method” incapsuleaza noul operator si clasele produselor

specifice platformelor. Fiecare platforma este modelata cu o calsa Factory derivata.

Page 6: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

5

Fig.2 –Diagrama UML reprezentând un model de implementare pentru Abstract Factory Design Pattern

( http://sourcemaking.com/files/v2/content/patterns/Abstract_Factory-2x.png)

Exemplu de implementare Abstract Factory:

Java:

public class FactoryFmProto { static class Expression { protected String str; public Expression(String s) { str = s; } public Expression cloan() { return null; } public String toString() {

Page 7: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

6

return str; } } static abstract class Factory { protected Expression prototype = null; public Expression makePhrase() { return prototype.cloan(); } public abstract Expression makeCompromise(); public abstract Expression makeGrade(); } static class PCFactory extends Factory { public PCFactory() { prototype = new PCPhrase(); } public Expression makeCompromise() { return new Expression("\"do it your way, any way, or no way\""); } public Expression makeGrade() { return new Expression("\"you pass, self-esteem intact\""); } } static class NotPCFactory extends Factory { public NotPCFactory() { prototype = new NotPCPhrase(); } public Expression makeCompromise() { return new Expression("\"my way, or the highway\""); } public Expression makeGrade() { return new Expression("\"take test, deal with the results\""); } } public static void main(String[] args) { Factory factory; if (args.length > 0) factory = new PCFactory(); else

Page 8: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

7

factory = new NotPCFactory(); for (int i = 0; i < 3; i++) System.out.print(factory.makePhrase() + " "); System.out.println(); System.out.println(factory.makeCompromise()); System.out.println(factory.makeGrade()); } static class PCPhrase extends Expression { static String[] list = { "\"animal companion\"", "\"vertically challenged\"", "\"factually inaccurate\"", "\"chronologically gifted\"" }; private static int next = 0; public PCPhrase() { super(list[next]); next = (next + 1) % list.length; } public Expression cloan() { return new PCPhrase(); } } static class NotPCPhrase extends Expression { private static String[] list = { "\"pet\"", "\"short\"", "\"lie\"", "\"old\"" }; private static int next = 0; public NotPCPhrase() { super(list[next]); next = (next + 1) % list.length; } public Expression cloan() { return new NotPCPhrase(); } } }

Page 9: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

8

Rezultatul va consta in:

"short" "lie" "old"

"my way, or the highway"

"take test, deal with the results"

"vertically challenged" "factually inaccurate" "chronologically gifted"

"do it your way, any way, or no way" "you pass, self-esteem intact"

2.2.Factory Method Design Pattern

Atribute:

Defineste o interfata pentru crearea unui obiect, dar lasa

subclasele sa decida care dintre clase va fi instantiata. Acest

model permite claselor cedarea instantierilor subclasei.

Defineste un constructor virtual .

Noul operator este considerat daunator .

Putem demosntra acest model de design astfel : producatorii de jucarii creaza jucariile

injectand plastic in mulaje de diferite forme . Tipul jucariei va fi determinat de forma mulajului.

Fig.3 –Diagrama UML reprezentând un model de implementare pentru Factory Method Design Pattern

(http://sourcemaking.com/files/v2/content/patterns/Factory_Method_example1-2x.png)

Page 10: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

9

Structura:

Punerea in aplicare a modelului Factory Method , se suprapune in mare masura cu cea a

Abstract Factory .

Fig.4 –Diagrama UML reprezentând un model de implementare pentru Factory Method Design Pattern (http://sourcemaking.com/files/v2/content/patterns/Factory_Method-2x.png)

O definitie populara a modelului Factory Method este : o metoda statica a unei clase

care returneaza un obiect de tipul acelei clase. Spre deosebire de un constructor , obiectul ce se

returneaza ar putea fi o instant a unei subclase si un obiect existent poate fi reutilizat in loc de a

crea unul nou.

Fig.5 –Diagrama UML reprezentând un model de implementare pentru Factory Method Design Pattern

(http://sourcemaking.com/files/v2/content/patterns/Factory_Method__-2x.png)

Page 11: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

10

Exemplu de implementare Factory Method :

Java:

public interface ImageReader {

public DecodedImage getDecodedImage();

}

public class GifReader implements ImageReader {

public GifReader( InputStream in ) {

// check that it's a gif, throw exception if it's not, then if it is

decode it.

}

public DecodedImage getDecodedImage() {

return decodedImage;

}

}

public class JpegReader implements ImageReader {

//... }

2.3.Prototype Design Pattern

Atribute:

Specifica tipul obiectelor care trebuie create cu ajutorul unei

instante prototip si creaza noi obiecte prin copierea acestui

prototip.

Racoleaza o instanta a unei clase pentru a fi utilizata pentru

creearea de noi instante.

Noul operator e considerat daunator.

Page 12: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

11

O exemplificare a acestui model o constituie diviziunea unei celule in doua celule identice .

http://sourcemaking.com/files/v2/content/patterns/Prototype_example1-2x.png

Structura:

http://sourcemaking.com/files/v2/content/patterns/Prototype-2x.png

Exemplu de implementare Prototype :

Page 13: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

12

Java:

public class FactoryProto {

interface Xyz { Xyz cloan(); } static class Tom implements Xyz { public Xyz cloan() { return new Tom(); } public String toString() { return "ttt"; } } static class Dick implements Xyz { public Xyz cloan() { return new Dick(); } public String toString() { return "ddd"; } } static class Harry implements Xyz { public Xyz cloan() { return new Harry(); } public String toString() { return "hhh"; } } static class Factory { private static java.util.Map prototypes = new java.util.HashMap(); static { prototypes.put( "tom", new Tom() ); prototypes.put( "dick", new Dick() ); prototypes.put( "harry", new Harry() ); } public static Xyz makeObject( String s ) { return ((Xyz)prototypes.get(s)).cloan(); } } public static void main( String[] args ) { for (int i=0; i < args.length; i++) { System.out.print( Factory.makeObject( args[i] ) + " " ); } }

}

Rezultatul va consta in:

tom dick tom harry tom ttt ddd ttt hhh ttt

Page 14: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

13

2.4.Singleton Design Pattern

Atribute:

Se asigura ca o clasa are o singura instanta si ofera un punct global

de acces la ea .

Incapsuleaza “initializarea la prima utilizare”

Problema : Aplicatia are nevoie de o singura instanță a unui obiect. În plus, initializare lenta și

accesul global sunt necesare.

Structura:

http://sourcemaking.com/files/v2/content/patterns/singleton1-2x.png

Clasa instantei este responsabila pentru access si pentru initializarea la prima utilizare. Instanta

unica este un atribut static si privat , iar functia accesor este o metoda static si publica.

http://sourcemaking.com/files/v2/content/patterns/Singleton-2x.png

Page 15: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

14

Exemplu de implementare Singleton:

Java:

public class Singleton {

// Private constructor prevents instantiation from other classes

private Singleton() {}

/**

* SingletonHolder is loaded on the first execution of

Singleton.getInstance()

* or the first access to SingletonHolder.INSTANCE, not before.

*/

private static class SingletonHolder {

private static final Singleton INSTANCE = new Singleton();

}

public static Singleton getInstance() {

return SingletonHolder.INSTANCE;

} }

3. Behavioral patterns

Un behavioral pattern explică modul în care obiectele interacționează. Acesta descrie modul in

care diferite obiecte si clase trimit mesaje unul altuia pentru a face lucrurile sa se intample si

cum etapele unei sarcini sunt împărțite între diferite obiecte.Impartirea etapelor se face prin

folosirea mostenirii.

In continuare se vor prezenta patru modele:Strategy,Template method,Iterator si Command.

Modelul Strategy încapsulează un algoritm într-un obiect. Acesta usureaza schimbarea

algoritmului pe care ifolosește un obiect.Modelul Command încapsulează o cerere într-un

obiect, astfel încât să poată fi transmisa ca parametru, stocate pe o listă istoric, sau manipulata

în alte moduri.

Template method este o definiție abstractă a unui algoritm. Aceasta definește pas cu pas algoritmul, fiecare pas invocănd fie o operație abstractă sau o operație primitiva. O subclasă detaliază algoritmul prin definirea operațiunilor abstracte.Modelul Iterator abstractizeaza modul in care accesam si parcurgem o colectie.

Page 16: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

15

3.1 Strategy pattern 3.2.1 Introducere Strategy pattern este un model care defineste o familie de algoritmi,incapsuleaza pe fiecare si

faciliteaza interschimbarea acestor algoritmi.Este util atunci cand vrem sa alegem unul din mai

multe comportamente posibile pentru o anumita clasa.Aceasta alegere depinde de clientul

care face cererea sau de datele asupra carora se actioneaza.

Design-ul acesta este folositor si atunci cand avem nevoie sa ascundem de utilizator detaliile de

implementare ale algoritmului .

Acest pattern se bazeaza pe urmatoarele principii:

1.Obiectele au scopuri clare.

2.Implementarea acestor scopuri se realizeaza prin intermediul polimorfismului.

3.Este necesar un mod de a administra implementari diferite al aceluiasi algoritm,conceptual

vorbind.

4.Trebuie evitate tehnicile care fac posibila modificarea unei clase de catre alta clasa.

5.Trebuie evitata duplicarea codului.

3.2.2 Structura si modul de functioare

Figura preluata din “Design patterns”-Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides

Page 17: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

16

Clasele participante :

-Strategy:este o interfata comuna pentru toti algoritmi implementati.Clasa Context foloseste

aceasta interfata pentru a apela algoritmul

definit in clasa Concrete Strategy;

-ConcreteStrategy:implementeaza algoritmul folosind interfata Strategy;

-Context:este configurata cu un obiect ConcreteStrategy;contine o referinta la un obiect

Strategy;poate sa defineasca interfata care sa permita clasei Strategy sa ii acceseze datele.

Clasele Strategy si Context interactioneaza pentru a implementa algoritmul ales.Un obiect de

tip context trimite toate datele necesare algoritmului

catre un obiect de tip Strategy atunci cand respectivul algoritm este apelat.O alta abordare este

sa fie folosita o referinta la context atunci cand este apelata obiectul Strategy.

Un context trimite mai departe catre Strategy cererile pe care le primeste de la obiectul

client,acesta lucrand exclusiv cu obiectul context.

Vom folosi acest pattern intr-un exemplu de cod preluat de pe

“java67.blogspot.ro/2014/12/strategy-pattern-in-java-with-sample.html.”

Algoritmii ce trebuie incapsulati in acest caz sunt algoritmi de ordonare:Bubble sort,Insert

sort,Quick sort si Merge sort.

public class Test {

public static void main(String args[]) throws InterruptedException {

int[] var = {1, 2, 3, 4, 5 };

Context ctx = new Context(new BubbleSort());//Initializam un obiect context care foloseste

Bubble Sort

ctx.arrange(var);

ctx = new Context(new QuickSort());//Putem schimba algoritmul folosit fara a modifica

clasa Context

ctx.arrange(var);

}

}

interface Strategy {

public void sort(int[] numbers);

}

class BubbleSort implements Strategy {

public void sort(int[] numbers) {

Page 18: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

17

System.out.println("ordonarea vectorului folosind bubble sort");

}

}

class InsertionSort implements Strategy {

public void sort(int[] numbers) {

System.out.println("ordonarea vectorului folosind insertion sort");

}

}

class QuickSort implements Strategy {

public void sort(int[] numbers) {

System.out.println("ordonarea vectorului folosind quick sort");

}

}

class MergeSort implements Strategy {

public void sort(int[] numbers) {

System.out.println("ordonarea vectorului folosind merge sort");

}

}

class Context {

private final Strategy strategy;

public Context(Strategy strategy) {

this.strategy = strategy;

}

public void arrange(int[] input) {

strategy.sort(input);

}

}

Output

ordonarea vectorului folosind bubble sort

ordonarea vectorului folosind quick sort

Dupa cum se poate observa schimbarea algoritmului se poate face usor ,nefiind necesara

modificarea clasei Context.

De-asemenea,daca dorim o implementare diferita a sortarii ,trebuie doar sa o incapsulam intr-o

clasa noua care sa implementeze interfata Strategy.

Page 19: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

18

3.2.3.Aspecte ale modelului

Acest model prezinta urmatoarele avantaje:

1)Incapsularea algoritmului in clase separate permite modificarea acestuia independent de

context,facilitand schimbarea

si extinderea comportamentului clasei Context.

2)Acest pattern reprezinta o alternativa la structurile conditionale folosite pentru selectarea

comportamentului

dorit.Acest structuri sunt folosite atunci cand posibilele comportamente ale unui clase sunt

definite chiar in clasa respectiva.

3)Ofera o serie de implementari ale aceluiasi comportament,clientul putand sa aleaga intre mai

multe strategii cu diferite performante.

Acest model prezinta urmatoarele dezavantaje:

1)Clientii trebuie sa stie cate strategii exista si cum difera acestea.

2)Clasele ConcreteStrategy folosesc aceeasi interfata,indiferent de gradul de complexitate al

algoritmilor pe care ii incapsuleaza.

Din acest motiv este posibil sa nu fie folosite toate informatiile primite prin interfata.Asta

inseamna ca vor fi exista parametrii

care sunt creati si initializati fara a fi folositi.

3)Va exista un numar mare de obiecte .

3.3 Template method

3.3.1 Introducere

Template method este un pattern folosit pentru a implementa partile constante ale

unui algoritm,permitand subclaselor sa stabileasca comportamentul care variaza.

Acest pattern ar trebui folosit atunci cand vrem sa grupam comportamentul comun

al mai multor subclase intr-o singura clasa,evitand cod duplicat.

Page 20: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

19

3.3.2 Structura si modul de functionare

Figura preluata din “Design patterns”-Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides

Clasele participante

-AbstractClass:defineste operatii primitive pe care subclasele le definesc pentru a implementa

pasii unui algoritm defineste o metoda template care descrie scheletul unui algoritm

-ConcreteClass:implementeaza operatiile primitive care realizeaza pasii algoritmului specifici

subclasei

ConcreteClass se bazeaza pe AbstractClass sa implementeze pasii invarianti ai algoritmului.

Exemplu de folosire al pattern-ului:http://www.journaldev.com/1763/template-method-

design-pattern-in-java

public abstract class HouseTemplate {

// metoda template

public final void buildHouse(){

buildFoundation();

buildPillars();

buildWalls();

buildWindows();

System.out.println("House is built.");

}

Page 21: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

20

private final void buildWindows() {

System.out.println("Building Glass Windows");

}

// operatiile primitive ce trebuie implementate de catre subclase

public abstract void buildWalls();

public abstract void buildPillars();

private final void buildFoundation() {

System.out.println("Building foundation with cement,iron rods and sand");

}

}

public class WoodenHouse extends HouseTemplate {

//subclasa modifica metodele care au o implementare necorespunzatoare

public void buildWalls() {

System.out.println("Building Wooden Walls");

}

public void buildPillars() {

System.out.println("Building Pillars with Wood coating");

}

}

public class GlassHouse extends HouseTemplate {

public void buildWalls() {

System.out.println("Building Glass Walls");

}

public void buildPillars() {

System.out.println("Building Pillars with glass coating");

}

}

3.3.3 Aspecte ale modelului

Metodele care sunt comune pentru toate subclasele raman in metoda template neschimbate,in

timp ce subclasele pot sa modifice metodele fara a se influenta unu pe alta.

Metodele abstracte trebuie implementate de catre subclase(de exemplu buildWalls si

buildPillars).

Page 22: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

21

In metoda Template pot sa existe si asa numitele metode hook a caror modificare ramane la

alegerea clientului.

Un obiectiv important în proiectarea metodelor template este de a reduce numărul de

operațiuni primitive pe care o subclasa trebuie să suprascrie pentru a concretiza algoritmul. Cu

cat mai multe operațiuni au nevoie de suprascriere, cu atat devin lucrurile mai plictisitoare

pentru clienti.

3.4 Iterator

3.4.1.Introducere

Acest design pattern ne ofera urmatoarele lucruri:

-un mod uniform de accesa diferite colectii de Objects fara a dezvalui reprezentarea interna a

acestora,

-moduri diferite de parcurgere a acestor colectii,

-parcurgeri multiple ale colectiilor

3.4.1.Structura si modul de functionare

Figura preluata din “Design patterns”-Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides

Clase participante:

1)Iterator,

2)ConcreteIterator,

Page 23: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

22

3)Aggregate ,

4)ConcreteAggregate.

Clasa Iterator defineste o interfata pentru accesarea si parcurgerea elementelor.

Metodele definite in aceasta clasa sunt folosite in acest scop:

First()-ne spune care este primul element

Next()- ne spune care este urmatorul element din colectie .

ConcreteIterator implementeaza interfata Iterator si tine cont de pozitia curenta in

parcurgerea colectiilor,putand sa determine obiectul urmator care trebuie parcurs

Aggregate defineste o interfata pentru realizarea unui obiect Iterator(metoda CreateIterator()

este folosita in acest sens)

ConcreteAggregate returneaza o instanta propriu-zisa de ConcreteIterator

O problema fundamentala care trebuie stabilita este cine controleaza iteratia:

Iteratorul sau clientul care foloseste iteratorul.

În cazul în care clientul controlează repetarea, iteratorul este numit un iterator extern, iar

atunci când iterator controlează, iterator este un iterator intern.

Iteratorii externi sunt mai flexibili decât iteratorii interne. Este ușor să se verifice daca două

colecții sunt egale cu un iterator extern, de exemplu, dar este practic imposibil cu iteratori

interni.

Clasa Iterator nu este singurul loc în care algoritmul de parcurgere poate fi definit. Clasa

Aggregate poate defini algoritmul de traversare și poate folosi iteratorul pentru a stoca doar

starea iterației. Acest tip de iterator se numeste cursor, deoarece indică numai poziția curentă.

Un client va invoca operația Nextl pe colectie cu cursorul ca un argument, iar operațiunea

viitoare va schimba starea cursorului.

În cazul în care iterator este responsabil pentru algoritmul de traversare, atunci poate folosi

diferiti algoritmi de iterație pe aceeasi colectie, și poate , de asemenea, să reutilizeze același

algoritm pe diferite colectii. Pe de altă parte, algoritmul de parcurgere ar putea avea nevoie sa

acceseze variabilele private ale agregatului. Dacă este așa, nu se respecta incapsularea colectiei.

Urmeaza un exemplu de cod Java in care este folosit acest pattern():

interface IIterator { public boolean hasNext(); public Object next(); }

Page 24: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

23

interface IContainer { public IIterator createIterator(); }

class BooksCollection implements IContainer { private String m_titles[] = {"Design Patterns","1","2","3","4"}; public IIterator createIterator() { BookIterator result = new BookIterator(); return result; } private class BookIterator implements IIterator { private int m_position; public boolean hasNext() { if (m_position < m_titles.length) return true; else return false; } public Object next() { if (this.hasNext()) return m_titles[m_position++]; else return null; } } }

Avem urmatoarele clase in acest exemplu:

- IIterator – Aceasta interfata reprezinta clasa AbstractIterator; - BookIterator – Implementarea clasei Iterator - IContainer – Interfata care defineste colectia - BooksCollection – Implementarea colectiilor

Page 25: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

24

3.4.3Aspecte ale modelului

O problema fundamentala care trebuie stabilita este cine controleaza iteratia:

Iteratorul sau clientul care foloseste iteratorul.

În cazul în care clientul controlează repetarea, iteratorul este numit un iterator extern, iar

atunci când iterator controlează, iterator este un iterator intern.

Iteratorii externi sunt mai flexibili decât iteratorii interne. Este ușor să se verifice daca două

colecții sunt egale cu un iterator extern, de exemplu, dar este practic imposibil cu iteratori

interni.

Clasa Iterator nu este singurul loc în care algoritmul de parcurgere poate fi definit. Clasa

Aggregate poate defini algoritmul de traversare și poate folosi iteratorul pentru a stoca doar

starea iterației. Acest tip de iterator se numeste cursor, deoarece indică numai poziția curentă.

Un client va invoca operația Nextl pe colectie cu cursorul ca un argument, iar operațiunea

viitoare va schimba starea cursorului.

În cazul în care iterator este responsabil pentru algoritmul de traversare, atunci poate folosi

diferiti algoritmi de iterație pe aceeasi colectie, și poate , de asemenea, să reutilizeze același

algoritm pe diferite colectii. Pe de altă parte, algoritmul de parcurgere ar putea avea nevoie sa

acceseze variabilele private ale agregatului. Dacă este așa, nu se respecta incapsularea colectiei.

3.5 Command pattern

3.5.1.Introducere

Command pattern-ul este un behavioral pattern in care un obiect este folosit pentru a

reprezenta si incapsula toata informatia necesara pentru a apela ulterior o metoda.

Uneori este necesar pentru a emite cereri de obiecte, fără să se știe nimic despre operațiunea

ce se solicită sau despre receptorul cererii. De exemplu, seturile de instrumente de UI(user

interface) includ obiecte precum butoane și meniuri care efectuează o cerere ca raspuns la

inputul utilizatorului..

Setul de instrumente insa nu poate pune în aplicare cererea în mod explicit în buton sau meniu,

pentru că numai aplicațiile care utilizează setul de instrumente știu ce trebuie făcut pe care

obiect.

Command pattern-ul le permite seturilor de instrumente sa faca cereri de obiecte

nespecificate prin transformarea cererii insesi intr-un obiect. Acest obiect poate fi stocat și

trimis ca orice alte obiecte. Cheia acestui model este o clasă abstractă de comandă, care

declară o interfață pentru operațiuni de executare. În cea mai simplă formă această interfață

include operatie abstracta Execute. Subclasele derivate din Command specifica o pereche

receptor-acțiune prin stocarea receptorului ca o variabilă instanță și prin punerea în aplicare a

Page 26: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

25

metodei Execute pentru a invoca cererea. Receptorul are cunoștințele necesare pentru a

îndeplini cererea.

3.5.2.Structura si modul de functionare

Figura preluata din “Design patterns”-Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides

Clasele participante:

1)Command- declara o interfata pentru executarea unei operatii,

2)ConcreteCommand- defineste o legatura intre un obiect receptor si o actiune,

3)Client- creeaza un obiect ConcreteCommand si stabileste receptorul lui,

4)Invoker- solicita comanda pentru a indeplini cererea,

5)Receiver- stie cum sa realizeze operatiile asociate cu indeplinirea unei cereri.

Urmeaza un exemplu de program care foloseste command pattern-ul preluat de pe

http://java.dzone.com/articles/design-patterns-command

1.Mai intai cream interfata de comanda

//Command public interface Command { public void execute(); }

2.Cream 2 ConcreteCommands:una pentru a aprinde lumina si una a pentru a stinge lumina

public class LightOnCommand implementsCommand { Light light;

Page 27: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

26

public LightOnCommand(Light light) { this.light = light; } public void execute() { light.switchOn(); } } public class LightOffCommand implementsCommand { Light light; public LightOffCommand(Light light) { this.light = light; } public void execute() { light.switchOff(); } } 3.Light este clasa Receiver

public class Light { private boolean on; public void switchOn() { on = true; } public void switchOff() { on = false; } }

Page 28: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

27

4.Clasa Invoker este reprezentata de RemoteControl

public class RemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void pressButton() { command.execute(); } }

5.Cream un Client pentru a folosi clasa Invoker

public class Client { public static void main(String[] args) { RemoteControl control = new RemoteControl(); Light light = new Light(); Command lightsOn = new LightsOnCommand(light); Command lightsOff = new LightsOffCommand(light); control.setCommand(lightsOn); control.pressButton(); control.setCommand(lightsOff); control.pressButton(); } }

3.5.3 Aspecte de implementare O comandă poate avea o gamă largă de abilități. Pe de o parte ea poate defini doar o legatura

între un receptor și acțiunile care realizează cererea,iar pe de alta parte poate implementa totul

.Cea din urmă varianta este utilă atunci când dorim să definim comenzi care sunt independente

de clase existente, atunci când nu există receptor adecvat, sau atunci când o comandă cunoaște

receptorul implicit.

Page 29: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

28

Comenzile pot realiza operatii de tip Undo și Redo dacă acestea oferă o modalitate de a inversa

executarea lor (de exemplu, o operatie Unexecute sau Undo).

Pentru a sprijini un nivel de undo, o aplicatie are nevoie sa stocheze doar comanda care a fost

executata ultima. Pentru niveluri multiple de Undo si Redo, aplicația are nevoie de o listă istoric

de comenzi care au fost executate, unde durata maximă a listei determină numărul de niveluri

undo / redo.Lista istorie stochează secvențe de comenzi care au fost executate. Traversează

înapoi prin listă și comenzile de executare inversa anulează efectul lor; traversează înaintează și

comenzile de executare le reexecuta

Acest mod de lucru este util atunci cand vrem sa structuram un sistem în jurul operațiunilor de

nivel înalt construite pe operatiuni primitive. O astfel de structură este comună sistemelor de

informații care acceptă tranzacții. O tranzacție încapsulează un set de modificări de date.

Command pattern-ul oferă o modalitate de a modela tranzacții. Comenzile au o interfață

comună, permitand invocarea tuturor tranzactiilor în același mod.Este, de asemenea, ușor de a

extinde sistemul cu noi tranzactii.

4.Structural Patterns

Principala sarcina a modelelor structurale (Structural patterns) consta in modul în care

clasele și obiectele sunt compuse pentru a forma structuri mai mari. Modelele de clasa

structurale folosesc conceptul de moștenire pentru a compune interfețe sau diverse

implementări. Ca un exemplu simplu,se ia în considerare, pentru conceptul de moștenire, cât

de mult se amestecă două sau mai multe clase întruna singura. Rezultatul va fi o clasă ce

combină proprietățile claselor sale mamă. Acest model este deosebit de util pentru construii

biblioteci de clase dezvoltate independent, dar care sa lucreze împreună. Un alt exemplu este

forma de clasă specifica pattern-ului Adapter. În general, un adaptor are rolul de a face ca o

interfață („adaptee”) sa fie conforma cu alta, oferind astfel o abstracție uniformă de interfețe

diferite. O clasa adaptor realizează acest lucru prin mostenirea privata dintr-o clasă adaptee.

Modelele structurale sunt:

Adapter – adaptează interfețele diferite ale claselor obiect;

Bridge – separa interfața unui obiect de implementarea acestuia;

Composite – creează o structura de tip arbore de obiecte simple si compuse;

Decorator – adaugă proprietăți obiectelor in mod dinamic;

Facade – creează o singura clasa ce poate reprezenta un întreg subsistem;

Flyweight – o instanțiere folosita pentru a realiza o partajare eficienta;

Private Class Data – controlează accesul la atributele clasei obiect;

Proxy – creează un obiect cu referință la un alt obiect;

Page 30: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

29

4.1.Adapter Design Pattern

Atribute:

Converteste interfata unei clase in interfata pe care clientul o asteapta sa o

primeasca. Astfel, clasele ce nu puteau functiona impreuna din cauza

incompabilitati dintre interfete, o pot face acum prin prisma Adaptorului.

Impacheteaza o clasa existenta intr-o interfata noua.

Reprezinta o punte a independetii privind folosirea unei componente vechi

intr-un sistem nou.

Problema aparitiei design-ului: atunci cand se doreste reutilizarea unei componente ce nu mai

este actuala, dar din punct de vedere tehnic ofera intreaga functionalitate necesara si nu este

compatibila cu filozofia si arhitectura sistemului in curs de dezvoltare.

http://sourcemaking.com/files/v2/content/patterns/Adapter_example1-2x.png

Adaptor presupune crearea unui abstracții intermediare care sa traduca, sau sa mapeze,

componenta veche la noul sistem. Clientii apeleaza metode asupra obiectului adaptor pe care le

redirecționează în apeluri la componenta de moștenire. Această strategie poate fi pusa în

aplicare fie cu metoda moștenirii sau cea de agregare.

Page 31: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

30

Adaptorul functioneaza ca un înveliș sau modificator al unei clase existente. Acesta oferă un

punct de vedere diferit sau tradus din clasa respectivă.

Structura: mai jos, se poate observa componenta display() a mostenirii Rectangle, ce asteapta

sa primeasca parametrii x,y,w si h, dar clientul vrea sa transmita x1 si y1 pentru coltul stanga

sus si x2 si y2 pentru coltul dreapta joc. Aceasta lipsa de coerenta dintre interfete poate fi

reconciliata prin adaugarea unui nivel suplimentare de indirectare, si anume un obiect adaptor.

http://sourcemaking.com/files/v2/content/patterns/Adapter_1-2x.png

Exemplu implementare pattern: (cod preluat de pe http://sourcemaking.com/design_patterns/adapter/java/1)

Inainte de implementare

Deoarece interfetele dintre obiectele Line si Rectangle sunt incompatibile, utilizatorul va tebuii

sa recupereze tipul fiecarei forme si sa livreze manual argumentele corecte.

Java: class LegacyLine

{

public void draw(int x1, int y1, int x2, int y2)

{

System.out.println("line from (" + x1 + ',' + y1 + ") to (" + x2 + ','

+ y2 + ')');

}

}

Page 32: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

31

class LegacyRectangle

{

public void draw(int x, int y, int w, int h)

{

System.out.println("rectangle at (" + x + ',' + y + ") with width " + w

+ " and height " + h);

}

}

public class AdapterDemo

{

public static void main(String[] args)

{

Object[] shapes =

{

new LegacyLine(), new LegacyRectangle()

};

// punctele de origine si de sfarsit ale editorului grafic

int x1 = 10, y1 = 20;

int x2 = 30, y2 = 60;

for (int i = 0; i < shapes.length; ++i)

if (shapes[i].getClass().getName().equals("LegacyLine"))

((LegacyLine)shapes[i]).draw(x1, y1, x2, y2);

else if (shapes[i].getClass().getName().equals("LegacyRectangle"))

((LegacyRectangle)shapes[i]).draw(Math.min(x1, x2), Math.min(y1, y2)

, Math.abs(x2 - x1), Math.abs(y2 - y1));

} }

Rezultatul va consta in: ”line from (10,20) to (30,60)”

“rectangle at (10,20) with width 20 and height 40”

Dupa de implementare

Nivelul suplimentar de indirectare al Adaptorului are grija sa mapeze o interfata comuna la

interfata specifica mostenita.

Java: class LegacyLine

{

public void draw(int x1, int y1, int x2, int y2)

{

System.out.println("line from (" + x1 + ',' + y1 + ") to (" + x2 + ','

+ y2 + ')');

}

}

class LegacyRectangle

{

Page 33: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

32

public void draw(int x, int y, int w, int h)

{

System.out.println("rectangle at (" + x + ',' + y + ") with width " + w

+ " and height " + h);

}

}

interface Shape

{

void draw(int x1, int y1, int x2, int y2);

}

class Line implements Shape

{

private LegacyLine adaptee = new LegacyLine();

public void draw(int x1, int y1, int x2, int y2)

{

adaptee.draw(x1, y1, x2, y2);

}

}

class Rectangle implements Shape

{

private LegacyRectangle adaptee = new LegacyRectangle();

public void draw(int x1, int y1, int x2, int y2)

{

adaptee.draw(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1),

Math.abs(y2 - y1));

}

}

public class AdapterDemo

{

public static void main(String[] args)

{

Shape[] shapes =

{

new Line(), new Rectangle()

};

// punctele de origine si de sfarsit ale editorului grafic

int x1 = 10, y1 = 20;

int x2 = 30, y2 = 60;

for (int i = 0; i < shapes.length; ++i)

shapes[i].draw(x1, y1, x2, y2);

} }

Rezultatul va consta in: ”line from (10,20) to (30,60)”

“rectangle at (10,20) with width 20 and height 40”

Page 34: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

33

4.2.Bridge Design Pattern

Atribute:

Separa o abstractie de implementarea sa, astfel incat cele doua pot varia

independent una fata de alta.

Publica interfata intr-o ierarhie mostenita, si trimite partea de

implementarea in propia ierarhie mostenire

Pattern-ul Bridge este un model structural de design care separă elementele abstracte ale unei

clase de la implementarea sa tehnică. Acest lucru oferă o implementare curata a obiectelor din

lumea reală și permite ca implementarea detaliilor poată fi schimbata cu ușurință.

Pattern-ul Bridge este un model foarte valoros, deoarece permite separarea elementelor

abstracte din clasa de detaliile necesare implementării. Acest model poate fi folosit, în cazul în

care clasa sufera modificari din cauza alterarii codului sursa, avand cunoștințe minime despre

program.

Problema aparitiei design-ului: Conceptul de "Hardening of the software arteries" (rigidizarea

arterelor software) a avut loc prin utilizarea unei subclase detinuta de o clasa abstracta de baza

pentru a oferii alternative in procesul de implementare. Acest lucru blocheaza timpul de

compilare dintre interfata si implementare. Abstractizarea si implementarea nu pot fi extinse si

compuse independent una fata de cealalta.

Structura: clientul nu vrea sa trateze detaliile legate de platforma. Pattern-ul Bridge

incapsuleaza aceasta complexitate in spatele unei abstractizari „wrapper”. Pattern-ul identifica

si deconecteaza interfata abstractizarii de implementarea abstractizata.

http://sourcemaking.com/files/v2/content/patterns/Bridge___-2x.png

Page 35: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

34

De exemplu un comutator de uz casnic pentru control luminii, ventilatiei, etc. este un astfel de

Bridge. Scopul comutatorul este de a pornii sau a oprii un dispozitiv. Comutatorul real poate fi

implementat simplu, comutator cu două poziții, sau un comutator variabil.

http://sourcemaking.com/files/v2/content/patterns/Bridge_example-2x.png

Exemplu implementare pattern: (cod preluat de pe http://www.gofpatterns.com/structural-design-

patterns/structural-patterns/bridgePattern-code.php)

Codul JAVA de mai jos pune in aplicare pattern-ul folosind ca exemplu o telecomanda TV.

Mai intai implementarea interfetei TV:

package com.java.structural.bridge; //Implementarea public interface TV{ public void on(); public void off(); public void tuneChannel(int channel); }

Sunt create doua implementari specifice: una pentru marca Sony si una pentru marca Samsung:

package com.java.structural.bridge; //Implementarea fizica

public class Sony implements TV{ public void on(){ //comanda pornit specifica Sony

} public void off(){

// comanda oprit specifica Sony }

public void tuneChannel(int channel){ // comanda “schimbare post” specifica Sony } }

Page 36: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

35

package com.java.structural.bridge; //Implementarea fizica

public class Samsung implements TV{ public void on(){ //comanda pornit specifica Samsung

} public void off(){

// comanda oprit specifica Samsung }

public void tuneChannel(int channel){ // comanda “schimbare post” specifica Samsung } }

Aceste clase se confrunta cu implementări specifice fiecarui producator de televizor. In

continuare este creata abstractia „telecomanda” pentru a controla TV-ul.

package com.java.structural.bridge; //Abstractia

public abstract class RemoteControl{ private TV implementor; public void on(){ implementor.on(); } public void off(){ implementor.off(); } public void setChannel(int channel){ implementor.tuneChannel(channel); } }

In timp ce “telecomanda” contine referinte despre TV poate delega metode de apelare prin intermediul interfetei. Pentru implementarea butoanelor de “+/-“ pentru navigarea intre canalele de televiziune, abstractia “telecomanda” trebuie extinsa pentru a contine acest concept: package com.java.structural.bridge; //Abstractie rafinata public class ConcreteRemote extends RemoteControl{ private int currentChannel; public void nextChannel(){ currentChannel++; setChannel(currentChannel); } public void prevChannel(){ currentChannel--; setChannel(currentChannel); } }

Page 37: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

36

Un dezavantaj major al acestui pattern, cu toate ca ofera o flexibilitate crescuta, este acela ca

va creste complexitatea programului.

4.3.Composite Design Pattern

Atribute:

Descompune obiectele in structuri de arbori pentru a reprezenta o ierarhie

intreaga.

Lasa clientii sa trateze obiectele individual si compunerea obiectelor

uniforma.

Compozitie recursiva.

Directoare ce contin intrari, acele intrari pot fi la randul lor alte directoare.

Problema aparitiei design-ului: aplicatiile au nevoie sa manipuleze ierarhic intreaga colectie de

obiecte „primitive” si „composite”. Procesarea celor „primitive” difera de cea a obiectelor

„composite”. Era nevoie ca inainte de inceperea procesarii obiectelor, acestea sa fie

„interogate” aflandu-se tipul acestor si ce metoda trebuie aplicata pentru satisfacerea

procesului. Acest lucru nu a fost dorit.

Structura: cosnsta in faptul ca o compozitie ce contine componente, aceste componente pot fi

la randul lor alte compozitii.

http://sourcemaking.com/files/v2/content/patterns/Composite-2x.png

Page 38: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

37

Un meniu ce contine intem-uri, fiecare din aceste item-uri poate fi la randul lui un alt meniu.

O expresie aritmetica ce presupune un operand, o operatie (+ - / * ) si un alt operand, poate

alcatuii un alt exemplu. Operand-ul poate fi un numar sau o alta expresie aritmetica. Asadar 2

+3 si (2+3)+(4*6), ambele sunt expresii valide.

http://sourcemaking.com/files/v2/content/patterns/Composite_example1-2x.png

Exemplu implementare pattern: Un atribut static în clasa de bază Entity poate fi manipulat prin

fiecare obiect Box pentru a controla procesul de indentare.

(cod preluat de pe http://sourcemaking.com/design_patterns/composite/java/3)

Java: import java.util.List;

import java.util.ArrayList;

abstract class Entity {

protected static StringBuffer indent = new StringBuffer();

public abstract void traverse();

}

class Product extends Entity {

private int value;

public Product( int val ) { value = val; }

public void traverse() {

System.out.println( indent.toString() + value );

} }

Page 39: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

38

class Box extends Entity {

private List children = new ArrayList();

private int value;

public Box( int val ) { value = val; }

public void add( Entity c ) { children.add( c ); }

public void traverse() {

System.out.println( indent.toString() + value );

indent.append( " " );

for (int i=0; i < children.size(); i++)

((Entity)children.get(i)).traverse();

indent.setLength( indent.length() - 3 );

} }

public class CompositeLevels {

public static void main( String[] args ) {

Box root = initialize();

root.traverse();

}

private static Box initialize() {

Box[] nodes = new Box[7];

nodes[1] = new Box( 1 );

int[] s = { 1, 4, 7 };

for (int i=0; i < 3; i++) {

nodes[2] = new Box( 21+i );

nodes[1].add( nodes[2] );

int lev = 3;

for (int j=0; j < 4; j++) {

nodes[lev-1].add( new Product( lev*10 + s[i] ) );

nodes[lev] = new Box( lev*10 + s[i]+1 );

nodes[lev-1].add( nodes[lev] );

nodes[lev-1].add( new Product( lev*10 + s[i]+2 ) );

lev++;

} }

return nodes[1]; } }

Page 40: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

39

Rezultatul va consta in:

1

21

31

32

41

42

51

52

61

62

63

53

43

33

22

34

35

44

45

54

55

64

65

66

56

46

36

23

37

38

47

48

57

58

67

68

69

59

49 39

Page 41: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

40

4.4.Decorator Design Pattern

Atribute:

Ataseaza propietati aditionale asupra unui obiect in mod dinamic.

Infrumuseteaza nucleul unui obiect la cererea unui client prin wrapping

recursiv.

Problema aparitiei design-ului: cand se vrea adaugarea unui comportament sau unei stari

asupra unui obiect individual in timpul executiei. Metoda mostenirii nu este posibila, deoarece

aceasta este statica si se aplica pentru intreaga clasa.

Solutia acestei probleme presupune incapsularea obiectului original in initeriorul unei interfete

abstracte wrapper. Atat obiectul decorator cat si obiectul nucleu moștenesc de aceasta

interfața abstracta. Interfata foloseste compunerea recursiva pentru a permite adaugarea unui

numar nelimitat de layere de tip decorator asupra fiecarui nucleu de obiect.

Dupa aplicarea pattern-ului identitatea nucleului a fost ascunsa inautr-ul obiectului decorator.

Incercarea accesarii nucleului obiectului in mod direct reprezinta acum, noua problema.

Structura: clientul este intotdeauna interesat in CoreFunctionality.doThis(). Clientul poate, sau

poate nu, sa reprezinte interes in OptionalOne.doThis() si in OptionalTwo.doThis(). Fiecare

dintre aceste clase trimite catre clasa de baza Decorator si aceasta clasa trimite la randul ei

catre obiectul “wrappee”.

http://sourcemaking.com/files/v2/content/patterns/Decorator__1-2x.png

Page 42: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

41

Exemplu implementare pattern:

(cod preluat de pe http://sourcemaking.com/design_patterns/decorator/java/3)

Java:

// 1. "lowest common denominator"

interface Widget {

void draw();

}

// 3. "Core" class with "is a" relationship

class TextField implements Widget {

private int width, height;

public TextField( int w, int h ) {

width = w;

height = h;

}

public void draw() {

System.out.println( "TextField: " + width + ", " + height );

}

}

// 2. Second level base class with "isa" relationship

abstract class Decorator implements Widget {

private Widget wid; // 4. "has a" relationship

public Decorator( Widget w ) {

wid = w;

}

// 5. Delegation

public void draw() {

wid.draw();

}

}

// 6. Optional embellishment

class BorderDecorator extends Decorator {

public BorderDecorator( Widget w ) {

super( w );

}

public void draw() {

Page 43: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

42

super.draw(); // 7. Delegate to base class and add extra stuff

System.out.println(" BorderDecorator");

}

}

// 6. Optional embellishment

class ScrollDecorator extends Decorator {

public ScrollDecorator( Widget w ) {

super( w );

}

public void draw() {

super.draw(); // 7. Delegate to base class and add extra stuff

System.out.println( " ScrollDecorator" );

}

}

public class DecoratorDemo {

public static void main( String[] args ) {

// 8. Client has the responsibility to compose desired configurations

Widget aWidget = new BorderDecorator(

new BorderDecorator(

new ScrollDecorator(

new TextField( 80, 24 ))));

aWidget.draw();

} }

Page 44: Design Patterns - stst.elia.pub.rostst.elia.pub.ro/news/IS/TEME_IS_2014_15/1_MihaiOc_DiaconescuRa... · cartea „Design Patterns: Elements of Reusable Object-Oriented Software a

43

5.Bibliografie:

1.” Design Patterns_ Elements of Reusable Object-Oriented Software” Erich Gamma, Richard

Helm, Ralph Johnson, John M. Vlissides

2. “Head First Design Patterns “Elisabeth Freeman, Eric Freeman, Bert Bates, Kathy Sierra

3.www. java67.blogspot.ro

4. www.journaldev.com

5. www.oodesign.com/iterator-pattern.html

6.www. java.dzone.com/

7. http://sourcemaking.com/