curs 6 modele de proiectare

98
Curs 6 They really need more design patterns

Upload: phungthu

Post on 07-Feb-2017

244 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Curs 6 Modele de proiectare

Curs 6

They really need more design patterns

Page 2: Curs 6 Modele de proiectare

Definiţia termenului patternConform dicţionarului Merriam-Webster

termenul de pattern înseamnă

1. o formă sau model propus pentru imitare

2. ceva proiectat sau folosit ca model pentru a face lucruri (calapodul croitorului)

3. o formă sau proiect

4. o configuraţie de evenimente

5. ruta prestabilită a unui avion

6. model comportamental

Are ca sinonim indicat termenul de model2

Page 3: Curs 6 Modele de proiectare

Termenul a apărut în cadrul studiilor realizate de arhitectul Christopher Alexander care căuta noi maniere pentru a proiecta clădiri şi zone urbane.

El spune că fiecare formă este o regulă cu trei părţi care explică relaţiile existente în cadrul unui anume context, problemă sau soluţie.

Astfel o definiţie curentă este “soluţia unei probleme într-un context”.

Aceste modele pot fi aplicate în diferite activităţi umane inclusiv în dezvoltarea programelor.

3

Page 4: Curs 6 Modele de proiectare

Istoricul

În 1987 Cunningham şi Beck au pornit de la idea lui Alexandru şi au dezvoltat un minilimbaj orientat pe modele pentru Smalltalk

În 1990 Gaşca celor patru – G4(Gamma, Helm, Johnson and Vlissides) a început scrierea unui catalog ce conţine astfel de modele de programe

1995 G4 publică cartea ce conţine experienţa lor în modele de proiectare

4

Page 5: Curs 6 Modele de proiectare

Riehle şi Zullighoven menţionează trei tipuri de modele software

Model conceptual

Model de proiectare

Model de programare

5

Page 6: Curs 6 Modele de proiectare

Modelele de proiectare se pot aplica la mai multe nivele de abstractizare

model complex

soluţia la o problemă generală (tratate de G4)

Proiectarea unei clase care poate fi reutilizată

6

Page 7: Curs 6 Modele de proiectare

În general, un model are 4 elemente esenţiale:

Numele:

Problema:

Soluţia:

Consecinţele r

7

Page 8: Curs 6 Modele de proiectare

Categorii de design Pattern din GoF

8

Scop

Creaţional Structural Comportamental

Domeniu

Clasă Fabrica Method Adapter (clasă) InterpreterTemplate Method

Obiect

Abstract FabricaBuilderPrototypeSingleton

Adapter (obiect)BridgeCompositeDecoratorFacadeFlyweightProxy

Chain of Responsibility

CommandIteratorMediatorMementoObserverStateStrategyVisitor

Page 9: Curs 6 Modele de proiectare

Relatii intre patter-urile din GoF

Page 10: Curs 6 Modele de proiectare

10

Clase abstracte si concrete

Clasa client participanta Clasa client implicita

Page 11: Curs 6 Modele de proiectare

Relatii intre clase

Comentariu in pseudocod

11

Page 12: Curs 6 Modele de proiectare

12

Page 13: Curs 6 Modele de proiectare

Avantajele folosirii modelelor de proiectare

Capturarea unei experienţe

Facilitează comunicarea între dezvoltatori

Face mai simplă reutilizarea unor modele

Uşurează modificările în proiect

îmbunătăţeşte lizibilitatea proiectului

13

Page 14: Curs 6 Modele de proiectare

Modele creationale

Abstractizeaza instantierea unui proces.

Exista doua caracteristici dominante

se incapsuleaza cunostiintele despreclasele concrete folosite de sistem

se ascunde maniera in care aceste clasesunt create si cooperarea lor

Page 15: Curs 6 Modele de proiectare

Fabrica de obiecte

Să se proiecteze o formă de citire a datelor care să primească un nume complet şi să-l împartă automat în nume şi prenume considerând virgula separator.

15

Page 16: Curs 6 Modele de proiectare

Class Nume

{ protected string prim;

protected string ultim;

public String IaPrim()

{ return prim; }

public String IaUltim()

{ return ultim; } }

Class SeparPrinSpatiu extends Nume

{ public SeparPrinSpatiu(s)

int i=s.lastIndexOf(“ ”);

if(i>0)

{ prim=s.substring(0,i).trim();

ultim=s.substring(i+1).trim(); }

else

{ prim=“”; last=s; } }

Class SeparPrinVirgula extendsNume

{ public SeparPrinVirgula(s)

int i=s.lastIndexOf(“,”);

if(i>0)

{ prim=s.substring(0,i).trim();

ultim=s.substring(i+1).trim(); }

else

{ prim=“”; last=s; }

}

16

Page 17: Curs 6 Modele de proiectare

class FabricaDeNume

{ public Nume DaNume(String SIn)

{ int i=Sin.indexOf(“,”);

if(i>0)

return newSeparPrinVirgula(SIn);

else

return new SeparPrinSpatiu(SIn);

}

}

În aceste condiţii folosirea este extrem de naturală:

….

FabricaDeNume NumeGen = newFabricaDeNume();//creez un obiect

. . . .

Private void CalculNume()

{

nume=NumeGen.DaNume(entryField.getText()); // citim numele dintr-o cutie de dialog cu utlizatorul

txPrimNume.setText(nume.IaPrim());

// afisăm în cutie primul nume

txUltimNume.setText(nume.IaUltim());// afisăm în cutie al doilea nume

}

17

Page 18: Curs 6 Modele de proiectare

Fabrica de obiecte - Când? De obicei această tehnică este proiectată atunci

când:

clasa nu poate anticipa ce tipuri de clase de obiecte trebuie să creeze

De asemenea mai există o serie de situaţii în care poate fi folosită această abordare

clasa de bază este abstractă iar modelul trebuie să întoarcă o clasă complet funcţională

clasa de bază conţine numai metode implicite şi se va deriva numai atunci când acestea nu sunt suficiente

… 18

Page 19: Curs 6 Modele de proiectare

Modelul fabrică abstractă O aplicaţie tipică a fabricii abstracte este atunci

când sistemul necesită interfeţe utilizator multiple cum ar fi în Win sau McIntosh.

În această situaţie i se spune fabricii cum se va dori să arate programul din punct de vedere al temei grafice (butoanele, ferestre etc) (de ex Win) şi el va întoarce o fabrica GUI care la rândul ei va trimite obiectele grafice ce se conformează standardului Win.

19

Page 20: Curs 6 Modele de proiectare
Page 21: Curs 6 Modele de proiectare

Look and feelString laf = UIManager.getSystemLookAndFeelClassName();

try {

UIManager.setLookAndFeel(laf);

}

catch (UnsupportedLookAndFeelException exc)

{

System.err.println("UnsupportedL&F: " + laf);

}

catch (Exception exc)

{

System.err.println("Error loading " + laf);

}

21

Page 22: Curs 6 Modele de proiectare

Exemplu Fabrica Abstracta

Exemplu Forma<<Interface>>

Patrat Cerc

<<creates>>

Page 23: Curs 6 Modele de proiectare

Exemplu Fabrica Abstracta

Forma<<Interface>>

Patrat Cerc

ImplementareFabricaForme

<<creates>>

Exemplu

FabricaForme<<Interface>>

makePatrat()makeCerc()

Page 24: Curs 6 Modele de proiectare

Exemplu Fabrica Abstracta

public interface FabricaForme {public Forma make (String FormaName) throws Exception

}public class ImplementareFabricaForme implements FabricaForme {

public Forma make(String FormaName) throws Exception {

if (FormaName.equals("Cerc")) return new Cerc();

else if (FormaName.equals("Patrat")) return new Patrat();

else throw new Exception("FabricaForme cannot create " + FormaName);

}

}………………………

private FabricaForme Fabrica;

Fabrica = new ImplementareFabricaForme();Forma s = Fabrica.make("Cerc");

Codul Rezultat

Page 25: Curs 6 Modele de proiectare

Exemplu Fabrica Abstracta

Page 26: Curs 6 Modele de proiectare

Metode fabrica

Structura

Page 27: Curs 6 Modele de proiectare

Modele structurale Descriu modalitatea de combinarea a claselor si

obiectelor pentru a putea forma structuri complexe.

Diferenta dintre modelele pentru clase si cele pentru obiecte se refera la faptul ca primele descriu

Maniera

Maniera

27

Page 28: Curs 6 Modele de proiectare

Modelul Adaptor Uneori o librărie sau un toolkit nu poate fi folosit

deoarece interfaţa este incompatibilă.

Nu se poate schimba interfaţa unei librării deoarece nu am acces la cod.

Chiar dacă există accesul la sursă nu este eficientă modificarea librăriei pentru fiecare nouă aplicaţie care se dezvoltă.

Un adaptor se foloseste:

28

Page 29: Curs 6 Modele de proiectare

Observatii de implementare Cit de mult trebuie aplicata metoda

o simpla conversie la nivel de interfata

seturi diferite de operatii

Mai este cunoscut si ca wrapper

Exista doua tipuri:

Pt clase

Pt obiecte

29

Page 30: Curs 6 Modele de proiectare

Un adaptor poate oferi o si dualitate

Un adaptor cu doua cai ofera atat interfata de Adaptare cit si interfata tinta.

Se observa ca avem un client care apeleaza adaptorul care la rindul lui apeleaza entitatea care a fost “Adaptata” aceasta isi indeplineste scopul si eventuale rezultate se intorc pe calea inversa

30

Page 31: Curs 6 Modele de proiectare

Exemplu Lamapa de birou

Switch

Light

+turnOn+turnOff

Lampa birou simpla

Ce este gresit la aceasta abordare

DIP (Dependency-Inversion Principle)

OCP (Open-Closed Principle )

Page 32: Curs 6 Modele de proiectare

Exemplu Lamapa de birou

Switch

Light

+turnOn+turnOff

O abordare gresita in extinderea

clasei Switch - DIP

FanSwitch

Fan

+turnOn+turnOff

Switch

<<Interface>>

Switchable+turnOn+turnOff

Light

+turnOn+turnOff

Solutia cu server Abstract

(DIP si OCP sunt OK)

(SRP) Single-Responsibility Principle

Page 33: Curs 6 Modele de proiectare

Solutia cu un ADAPTOR

Switch

<<Interface>>

Switchable+turnOn+turnOff

Light Adapter

+turnOn+turnOff

Light

+turnOn+turnOff

<<delegates>>

Solutia cu o clasa din ADAPTER

Switch

<<Interface>>

Switchable+turnOn+turnOff

Light Adapter

+turnOn+turnOff

Light

+turnOn+turnOff

Page 34: Curs 6 Modele de proiectare

Adaptor la nivel de interfata (Java)

Page 35: Curs 6 Modele de proiectare

Adaptor la nivel de clasa (CPP)

Page 36: Curs 6 Modele de proiectare

Adaptor cu delegare si mostenire

Page 37: Curs 6 Modele de proiectare

Adaptor - ExempluClient Code:

Adaptee a = new Adaptee(); Target t = new Adapter(a);

public void test() { t.request(); }

Target Code:class Target {

public void request() {}

}

Adaptee Code:

class Adaptee{

public void specificRequest() {System.out.println("Adaptee: SpecificRequest"); }

}

Adapter Code:class Adapter extends Target{private Adaptee adaptee;public Adapter(Adaptee a)

{ adaptee = a;}public void request()

{ adaptee.specificRequest();}}

Page 38: Curs 6 Modele de proiectare

Obiect Adaptor

Enumeration

hasMoreElements()

nextElement()

<<Interface>>ServicesEnumeration

hasMoreElements()

nextElement()

RegiteredServices

numServices()

getService()

-adaptee

Client

Page 39: Curs 6 Modele de proiectare

Obiect Adaptor

public class ServicesEnumeration implements Enumeration {public boolean hasMoreElements() {return this.currentServiceIdx <= adaptee.numServices();}

public Object nextElement() {if (!this.hasMoreElements())

{ throw new NoSuchElementException();}return adaptee.getService(this.currentSerrviceIdx++);

}}

Page 40: Curs 6 Modele de proiectare

Adaptor – Exemplu Modem<<Interface>>

Modem

+dial+hangup+send+receive

Hayes Modem

Robotics Modem

Ernie’s Modem

Modem ClientsModem Clients

Problema:

Sa presupunem ca sunt sute de clienti modem care vor folosi interfata Modem.

Sa mai presupunem ca acestora li s-a livrat un nou tip de modem (dedicat -Ded) care nu i se mai da numarul .

Sunt o serie de aplicatii noi care folosesc acest tip de modem si nu se obosesc sa faca numarul.

Toti clientii modem trebuie sa fie capabili sa foloseasca acestemodemuri dedicate fara a-si modifica aplicatia.

Page 41: Curs 6 Modele de proiectare

Adaptor – Exemplu Modem

Solutia ideala a problemei modemului

<<Interface>>

Dialler+dial+hangup

Hayes Modem

Robotics Modem

Ernie’s Modem

Modem ClientsModem Clients

<<Interface>>

Modem+send+receive

Ded Users

Dedicated Modem

Page 42: Curs 6 Modele de proiectare

Adaptor – Exemplu Modem

Rezolvarea cu ADAPTER

<<Interface>>

Modem

+dial+hangup+send+receive

Hayes Modem

Robotics Modem

Ernie’s Modem

Modem ClientsModem Clients

Dedicated Modem Adapter

DedicatedModem

+send+receive

Ded UsersDed Users<<delegates>>

Page 43: Curs 6 Modele de proiectare

Bridge

Decupleaza o abstractizare de implementarea ei astfelincat cele doua por varia indepemdent

43

Page 44: Curs 6 Modele de proiectare

Bridge – exemplu Modem

Modem

DialModem DedicatedModem

Hayes Dial Modem

USR Dial Modem

Ernies Dial Modem

Hayes Dedicated Modem

USR Dedicated Modem

Ernies Dedicated Modem

Page 45: Curs 6 Modele de proiectare

Bridge Pattern – Modem example<<interface>>ModemImplementation

+dial+hangup+send+receive

Hayes Modem

USR Modem

Ernies Modem

Modem ClientsModem Clients

<<Interface>>

Modem

+send+receive

Ded UsersDed Users

<<Interface>>

Modem

+dial+hangup+send+receive

ModemConnectionController

#dialImp#hangupImp#sendImp#receiveImp+dial+hangup+send+receive

DedModemController

+dial+hangup+send+receive

DialModemController

+dial+hangup+send+receive

<<delegates>>

Dial si Hangup sunt implementatepentrua simula starea conexiunii. Send si Receive deleaga catreimplementarile lor

TOATE metodeledeleaga catreimplementarile lor

Page 46: Curs 6 Modele de proiectare

Bridge

Car

Ford Toyota Sporty Truck

SportyFord ToyotaTruck FordTruck SportyToyota

Page 47: Curs 6 Modele de proiectare

Bridge

Ford ToyotaSporty Truck

Car CarManufacturer

Page 48: Curs 6 Modele de proiectare

Bridge

Page 49: Curs 6 Modele de proiectare

Bridge Pattern - exampleClient Code:public void test1() { ClientService1 cs1 = new ClientService1(new Implementation1());

cs1.serviceA(); cs1.serviceB(); }public void test2() { ClientService1 cs1 = new ClientService1(new Implementation2());

cs1.serviceA(); cs1.serviceB(); }public void test3() { ClientService2 cs2 = new ClientService2(new Implementation1());

cs2.serviceC(); cs2.serviceD(); cs2.serviceE();}}

Abstraction Code:class Abstraction {

private Implementation implementation;public Abstraction(Implementation imp) { implementation = imp;}public void service1() {implementation.facility1(); implementation.facility2(); }public void service2() {implementation.facility2(); implementation.facility3(); }public void service3() {implementation.facility1(); implementation.facility2();

implementation.facility4();}protected Implementation getImplementation() {return implementation;}

}class ClientService1 extends Abstraction {

public ClientService1(Implementation imp) { super(imp); }public void serviceA() {service1(); service2();} public void serviceB() {service3();}}

class ClientService2 extends Abstraction {public ClientService2(Implementation imp) { super(imp); }public void serviceC() {service2(); service3();} public void serviceD() {service1(); service3();}public void serviceE() {getImplementation().facility3();}}

Page 50: Curs 6 Modele de proiectare

Bridge Pattern - exampleImplementation Code:interface Implementation { void facility1(); void facility2(); void facility3(); void facility4();}

class Library1 { public void method1() {System.out.println("Library1.method1()");}public void method2() {System.out.println("Library1.method2()"); }}

class Library2 {public void operation1() {System.out.println("Library2.operation1()");}public void operation2() {System.out.println("Library2.operation2()");}public void operation3() {System.out.println("Library2.operation3()");}}

class Implementation1 implements Implementation {private Library1 delegate = new Library1();public void facility1() {System.out.println("Implementation1.facility1"); delegate.method1(); }public void facility2() {System.out.println("Implementation1.facility2"); delegate.method2(); }public void facility3() {System.out.println("Implementation1.facility3");

delegate.method2(); delegate.method1();}public void facility4() {System.out.println("Implementation1.facility4"); delegate.method1();}

}class Implementation2 implements Implementation {private Library2 delegate = new Library2();public void facility1() {System.out.println("Implementation2.facility1");delegate.operation1();}public void facility2() {System.out.println("Implementation2.facility2");delegate.operation2();}public void facility3() {System.out.println("Implementation2.facility3");delegate.operation3();}public void facility4() {System.out.println("Implementation2.facility4");delegate.operation1();}

}

Page 51: Curs 6 Modele de proiectare

Composite Exemplu

: Assembly

: Part

: CatalogueEntry

name = “screw”

O ierarhie de asamblare

: Part

: Part

: CatalogueEntry

name = “strut”

: Assembly

Contains Contains

Contains Contains

Problema:

Page 52: Curs 6 Modele de proiectare

Composite

Component

+ cost() : double

0..1

n

Part

+ cost() : double

Assembly

+ cost() : double

Solutie:

Page 53: Curs 6 Modele de proiectare

Compositepublic abstract class Component

{ public abstract double cost () ; }public class Part extends Component

{ public double cost ()

{ return entry.getCost(); }}public class Assembly extends Component

{ private Vector components = new Vector();public double cost()

{ double total = 0.0; Enumeration enum = components. elements();while (enum.hasMoreElements())

{ total += ((Component)enum.nextElement()).cost();}return total;

} }

Page 54: Curs 6 Modele de proiectare

Composite

Page 55: Curs 6 Modele de proiectare

Facade

Page 56: Curs 6 Modele de proiectare

Arhitectura deschisa

Page 57: Curs 6 Modele de proiectare

Arhitectura inchisa

Page 58: Curs 6 Modele de proiectare

Un exemplu de apel

public class HotelBooker{ public ArrayList<Hotel> getHotelNamesFor(Date from, Date to)

{//returns hotels available in the particular date range}} public class FlightBooker{ public ArrayList<Flight> getFlightsFor(Date from, Date to)

{//returns flights available in the particular date range}}

58

Page 59: Curs 6 Modele de proiectare

public class TravelFacade{

private HotelBooker hotelBooker;private FlightBooker flightBooker; public void getFlightsAndHotels(Date from, Data to)

{

ArrayList<Flight> flights = flightBooker.getFlightsFor(from, to);ArrayList<Hotel> hotels = hotelBooker.getHotelsFor(from, to);//process and return}

}

public class Client{public static void main(String[] args)

{TravelFacade facade = new TravelFacade(); facade.getFlightsAndHotels(from, to);}

} 59

Page 60: Curs 6 Modele de proiectare

Sabloane comportamentale Se ocupa de descrierea modelelor de comunicare intre

clase.

De fapt descriu fluxul complet de control al unei aplicatii.

Ele se folosesc de obieci mostenirea pentru cazul in care se plica claselor si compuenrea obiectelor in cealalta situatie.

60

Page 61: Curs 6 Modele de proiectare

Modelul Lant de responsabilitati Acesta evita cuplarea intre expeditorul si destinatarul unei

cereri acordând mai multor obiecte posibilitatea de a rezolva cerea.

Un exemplu de aplicație in care se poate folosi ar fi realizarea unei componente de asistenta sensibila la context pentru o interfața grafica cu utilizatorul unde utilizatorul poate obține informația suplimentara din orice zona a interfeței grafice printr-un simplu click.

Cea mai buna abordare ar fi organizarea informației suplimentare de ajutor in acord cu nivelul ei de generalitate

Apare problema ca obiectul care va raspunde la cererea de ajutor nu este explicit cunoscut de catre obiectul din interfata grafica (buton cutie de dialog etc) care initiazarespectiva cerere.

61

Page 62: Curs 6 Modele de proiectare

Sa presupunem ca utilizatorul cere asistenta din zona unui buton marcat ca print.

62

Page 63: Curs 6 Modele de proiectare

Pentru a putea transmite cererea in maniera de mai sus fiecare obiect trebuie sa partajeze o interfata comuna folosita fie pentru rezolvarea cererilor fie pentru accesarea succesorului din lant.

Exista componentele normale si o clasa mixin care permite crearea claselor widget care isi pot desena priopriile margini.

Acealasi efect poate fi obtinut si prin adaugarea de comportamente suplimentare la clasele mostenite

63

Page 64: Curs 6 Modele de proiectare

64

Page 65: Curs 6 Modele de proiectare

Unde o structura tipica de inlantuire de obiecte ar arata

65

Page 66: Curs 6 Modele de proiectare

La implementarea lantului de succesori avem doua posibilitati

Definirea de noi legaturi atat la nivelul clasei Handlersau la nivelul ConcreteHandler

Utilizarea legaturilor existente caz in care incercam sa folosim lanturile deja implementate. Atunci se evita definirea de legaturi explicite si se salveaza spatiu.

66

Page 67: Curs 6 Modele de proiectare

public class Handler

{

private Handler successor;

public void setSuccessor( Handler successor )

{ this.successor = successor;}

public Handler getSuccessor()

{return successor; }

public void handleRequest()

{successor.handleRequest(); }

}

67

Page 68: Curs 6 Modele de proiectare

public class ConcreteHandler2 extends Handler{

public void handleRequest()

{// executa o mica procesare asupra cererii si apoi trimite-o urmatorului din lant

getSuccessor().handleRequest();}

}

public class ConcreteHandler1 extends Handler{

public void handleRequest()

{// se presupune ca aici cererea trebuie tratata

if( expresia ce verifica daca cererea trb tratata aici == TRUE ){// trataeaza cerera. }

else getSuccessor().handleRequest();

}

} 68

Page 69: Curs 6 Modele de proiectare

public class Test{

public static void main( String arg[] ) {

try {

Handler handler1 = new ConcreteHandler1();

Handler handler2 = new ConcreteHandler1();

Handler handler3 = new ConcreteHandler1();

Handler handler4 = new ConcreteHandler1();

handler1.setSuccessor( handler2 );//incep crearea lant

handler2.setSuccessor( handler3 );

handler3.setSuccessor( handler4 );

handler1.handleRequest(); }

catch( Exception e ) {e.printStackTrace();}

}}69

Page 70: Curs 6 Modele de proiectare

Observator Aceasta abordare a aparut in urma unor constringeri

contrare.

Pe de o parte acest tip de interactiune este necesara si trebuie sa fie cit mai eficienta dar pe de alta o prima rezolvare ar conduce la o cuplare prea strinsa a claselor fapt ce nu este dorit deoarece scade dramatic posibilitatea de reutilizare a acestora.

Un exemplu tipic de aplicabilitate este in cazul interfetelor grafice ale unei aplicatii unde este necesara atat o separarea clara a acestora de datele de baza ale aplicatiei cit si o strinsa cooperare intre ele.

70

Page 71: Curs 6 Modele de proiectare

Aceasta tehnica se utilizeaza cind:

abstractizare are doua aspecte unul depinzind de celalat. Incapsularea acestor obiecte separate permite ca sa fie modificate si reutilizate independent

Modificarea.

anuntarea

71

Page 72: Curs 6 Modele de proiectare

72

Page 73: Curs 6 Modele de proiectare

73

Page 74: Curs 6 Modele de proiectare

Observer in Java

Page 75: Curs 6 Modele de proiectare

75

metoda Descriere

addObserver(Observer o) adauga un obiecte trimis ca argument catre listainterna de observatori.

deleteObserver (Observer o) Sterge din lista

deleteObservers() Sterge toti observatorii

notifyObservers (Object arg) daca obiectul curent a fost setat ca modificat(cu setChanged) apeleaza metoda update() a tuturor observatorilor din lista si le trimite nouaversiune a obiectului curent

notifyObservers() Similara cu anterioara dar fara argumente

countObservers() Numarul curent de observatori atasati unuiobiect observat

setChanged() Anunta ca starea obiect se schimbaSets the current object as changed.

hasChanged() True daca obiectul a fost setata ca schimbat

clearChanged() Reseteaza starea obiect curent la neschimbata(tot protected.)

Page 76: Curs 6 Modele de proiectare

Exemple: O componenta GUI “observa” o persoana

Page 77: Curs 6 Modele de proiectare
Page 78: Curs 6 Modele de proiectare

Java AWT 1.1 Event Model

Page 79: Curs 6 Modele de proiectare

event-driven programming

Page 80: Curs 6 Modele de proiectare

Example: event-driven programmingimport javax.swing.*; import java.awt.event.*; import java.awt.*;

import com.bruceeckel.swing.*;

public class Button2 extends JApplet {

JButton b1 = new JButton("Button 1"), b2 = new JButton("Button 2");

JTextField txt = new JTextField(10);

class BL implements ActionListener {

public void actionPerformed(ActionEvent e){

String name = ((JButton)e.getSource()).getText(); txt.setText(name);}

}

BL al = new BL();

public void init() {

b1.addActionListener(al); b2.addActionListener(al);

Container cp = getContentPane(); cp.setLayout(new FlowLayout());

cp.add(b1); cp.add(b2); cp.add(txt); }

public static void main(String[] args) {Console.run(new Button2(), 200, 75);}

}

Tratare

Eveniment

Surseeveniment

Evenimente

Inregistrarea gestionarevenimente la sursa lor

Page 81: Curs 6 Modele de proiectare

Modelul stare – State

81

Page 82: Curs 6 Modele de proiectare

public class Context{private State state;public void setState( State state )

{ this.state = state;}public State getState()

{ return state;}public void request(){state.handle();}

}public interface State{ void handle(); }

public class ConcreteStateB implements State{ public void handle()

{ }}

public class ConcreteStateA implements State{ public void handle()

{ }}public class Test{ public static void main( String arg[] )

{ try{State state = new ConcreteStateA();Context context = new Context();context.setState( state );context.request();}

catch( Exception e ){ e.printStackTrace();}

}}

82

Page 83: Curs 6 Modele de proiectare

Modelarea masinii TCP

83

Page 84: Curs 6 Modele de proiectare

Exista situatii in care avem foarte multe stari si mai mult acestea nu sunt asa de clar delimitate ca in cazul sa spunem al modelarii conexiunii tcp.

84

Page 85: Curs 6 Modele de proiectare

85

Page 86: Curs 6 Modele de proiectare

Intai clientul va crea un numar oarecare de instante ale clasei Stare

Apoi va crea instantele Tranzition si le va aduga la instantele State selectate.

In sfirsit va crea StateMachine prin transmiterea catreea a unei referinte catre instanta State initiala.

La apelul metodei Step din StateMachine ea va delega intern un apel catre instanta curenta a clasei Stare care va verifica daca o tranzitie care are simbolul dat (de exemplu obiectul parametru) a fost anterior definite.

Functie de aceasta metoda respective va decide daca va crea si intoarce o noua instanta de tip State care sa fie definite de Transition sau va genera o exceptie.

86

Page 87: Curs 6 Modele de proiectare

Modelul proxy Acesta asigura pentru un alt obiect un intermediar

sau inlocuior in scopul controlarii accesului la acesta.

Are principalul or de securitate deoarece permite realizarea unor filtrari functie de necesitati a fluxului de date.

87

Page 88: Curs 6 Modele de proiectare

88

Page 89: Curs 6 Modele de proiectare

Proxy pentru imagini swingimport java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class VirtualProxyTest extends JFrame {

private static String IMAGE_NAME = "mandrill.jpg";

private static int IMAGE_WIDTH = 256, IMAGE_HEIGHT = 256,

SPACING = 5, FRAME_X = 150, FRAME_Y = 200, FRAME_WIDTH = 530,

FRAME_HEIGHT = 286;

private Icon imageIcon = null, imageIconProxy = null;

static public void main(String args[]) {

VirtualProxyTest app = new VirtualProxyTest();

app.show();

}89

Page 90: Curs 6 Modele de proiectare

public VirtualProxyTest() {

super("Virtual Proxy Test");

// creaza iconita imaginii si proxy asociat ei.

imageIcon = new ImageIcon(IMAGE_NAME);

imageIconProxy = new ImageIconProxy(IMAGE_NAME, IMAGE_WIDTH, IMAGE_HEIGHT);

// seteaza dimensiunile frame si operatia implicita a acestuia

setBounds(FRAME_X, FRAME_Y, FRAME_WIDTH, FRAME_HEIGHT);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public void paint(Graphics g) {

super.paint(g);

Insets insets = getInsets();

imageIcon.paintIcon(this, g, insets.left, insets.top);

imageIconProxy.paintIcon(this, g,

insets.left + IMAGE_WIDTH + SPACING, // width

insets.top); // height

}

} 90

Page 91: Curs 6 Modele de proiectare

Interfata javax.swing.Icon care definesteelementele esentiale ale icoanelor Swing include trei metode paintIcon(), getIconWidth(), si getIconHeight.

Clasa ImageIcon care implementeazainterfata Icon mai adauga metode suplimentare.

Icoanele imagine poate mentine de asemenea o descriere si o referinta catreimagini

91

Page 92: Curs 6 Modele de proiectare

92

Page 93: Curs 6 Modele de proiectare

class ImageIconProxy implements javax.swing.Icon {

private Icon realIcon = null;

boolean isIconCreated = false;

private String imageName;

private int width, height;

public ImageIconProxy(String imageName, int width, int height){

this.imageName = imageName;

this.width = width;

this.height = height; }

public int getIconHeight() {

return isIconCreated ? height : realIcon.getIconHeight(); }

public int getIconWidth() {

return isIconCreated realIcon == null ? width : realIcon.getIconWidth();

}93

Page 94: Curs 6 Modele de proiectare

public void paintIcon(final Component c, Graphics g, int x, int y) {if(isIconCreated) {

realIcon.paintIcon(c, g, x, y); }else {g.drawRect(x, y, width-1, height-1);g.drawString("Loading image...", x+20,

y+20);// iconita este creata (deci imaginea se

incarca pe alt fir de executie. synchronized(this) {SwingUtilities.invokeLater(new

Runnable() {public void run() {try {

// intarzie procesul de incarcare a imaginii.

Thread.currentThread().sleep(2000);

//constructirul lui ImageIcon va crea//imaginea.

realIcon = new ImageIcon(imageName);

isIconCreated = true;}

catch(InterruptedException ex) {ex.printStackTrace();

}// reafiseaza componentele iconitei dupa//ce aceasta a fost creata.

c.repaint();}

});}

}}

}

94

Page 95: Curs 6 Modele de proiectare

ImageIconProxy mentine o referinta catre o icoana reala cu ajutorul variabilei membru realIcon.

La prima afisare a proxy icoana reala este creata intr-un thread separat pentru a permite dreptunghiului si textului sa fie afisat deoarece apelurile g.drawRect() si g.drawString() nu au efect pina la iesirea din metoda paintIcon().

Dupa ce icoana reala este creata si deci imaginea este incarcata componenta care afiseaza icoana este reafisata.

Mai jos este o diagrama de evenimente.

95

Page 96: Curs 6 Modele de proiectare

96

Page 97: Curs 6 Modele de proiectare

Referinte http://ooad.se.sjtu.edu.cn/ppt/Chap%206%20-

%20Design%20Patterns.ppt

http://www.vincehuston.org/dp/

http://www.dre.vanderbilt.edu/~schmidt/LiveLessons/#JavaSourceCode

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

http://www.yaldex.com/java_tutorial/0939352869.htm

97

Page 98: Curs 6 Modele de proiectare

I applied design patterns and look what is happened?!

98