L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

13

Click here to load reader

Transcript of L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

Page 1: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

DesignPatterns

DesignPatterns

Luca Lista, Vincenzo Innocente

Page 2: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

Design PatternsDesign Patterns

“Elementi di software OO riutilizzabile”

• Piccoli insiemi di classi che collaborano implementando dei comportamenti tipici– Creational patterns– Structural patterns– Behavioral patterns

Alcuni pattern classici stanno diventanto obsoleti grazie al

supporto dei Template

E. Gamma et al., Design Patterns

Page 3: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

FactoryFactory

AbstractProduct

ConcreteProduct1 ConcreteProduct2

Factory

createProduct1 () : AbstractProductcreateProduct2 () : AbstractProduct

Client

I client possono richiedere la creazione di un prodotto senza dipendervi.

La Factory dipende dai prodotti concreti, mentre i client dipendono solo AbstractProduct.

Page 4: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

SingletonSingleton

Il Singleton pattern piò essere usato ogni volta che una classe deve essere instanziata una sola volta, e viene usata da diversi oggetti.

Per evitare istanziazione accidentale, il constructor deve essere privato.

Più istanze, ma in numero ben determinato, possono esistere (multiton)

Siccome vengono usate funzioni statiche, l’ereditarietà non può essere applicata.

Singleton

_instance : Singleton

instance () : SingletonspecificService ()

if (_instance==0) _instance = new Singleton(); return _instance;

user_code() { Singleton::instance()->specificService(...);}

user_code() { Singleton::instance()->specificService(...);}

Page 5: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

Template SingletonTemplate Singleton

Un Template Singleton può essere specializzato usando la classe stessa come argomento del template.Se V ha un constructor privato, Singleton<V> deve essere friend di V (non tutti i compilatori lo supportano…).

if (_instance==0) _instance = new T(); return _instance;

Singleton

_instance : T

instance () : T

V

V( )specificService( )

Singleton{V}

T

class V : public Singleton<V> {public: specificService(...);private: V(); friend class Singleton<V>;};

user_code() { V::instance()->specificService(...);}

class V : public Singleton<V> {public: specificService(...);private: V(); friend class Singleton<V>;};

user_code() { V::instance()->specificService(...);}

Page 6: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

ProxyProxy

Una richiesta da un client a un server, può esseremediata dal Proxy, che può compiere anche altre operazioni (I/O, caching, etc.)

Subject

request( )

RealSubject

request( )

Proxy

_subject : RealSubject

request( )11

Client

_subject

. . ._subject->request();. . .

Page 7: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

CompositeComposite

Leaf

operation( )

Component

operation( )

Composite

operation( )

1..*1..*

Client

for c in all _children c->operation();

_children

Il client può trattare componenti e compositi usando la stessa interfaccia. La composizione può essere recursiva.

Esempio: programmi di grafica vettoriale

Page 8: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

Composite ShapeComposite Shape

Cerchio, Rettangolo, ...

draw( )

Shape

draw( )

Gruppo

draw( )

1..*1..*

Client

for c in all _children c->draw();

_children

Nel nostro esempio di grafica con Shapes un gruppo può essere considerato un compositoe le varie classi concretesono le leaves.

Page 9: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

Collection e IteratorCollection e Iterator

Un iteratore permette più iterazioni indipendenti sulla stessa collezione. Questo sarebbe stato impossibile se l’iterazione fosse stato un servizio della collezione.

Oggi, sia Collection che Iterator sono implementati come template classes (collezione “non intrusiva”).

Collection

_elements : Element

append (Element)remove (Element)... ()

Element

1

0..n

_elements

Iterator

rewind ()next () : Element*more () : bool

friend

Page 10: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

StrategyStrategyIl pattern Strategy permette di scegliere l’algoritmo da eseguire a run-time.

Nuovi algoritmi possono essere introdotti senza modificare i client.

ConcreteStrategyA

doAlgorithm( )

ConcreteStrategyB

doAlgorithm( )

ConcreteStrategyC

doAlgorithm( )

Client Strategy

doAlgorithm( )

{ . . . Strategy* s; s->doAlgorithm(); . . .}

Page 11: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

ObserverObserver

Lo stato dell’Observer dipende dallo stato del Subject.

Il Subject notifica a tutti gli Observer registrati che il suo stato è cambiato.

Observer

update( )Subject

_observers : Observer

attach (Observer)notify ()

0..*0..*

for all o in _observables o->update();

_observers

return _status;_status = _subject->status();

ConcreteSubject

_status : Status

status( )

ConcreteObserver

_status : Status_subject . ConcreteSubject

update( )

_subject

Page 12: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

Template MethodTemplate Method

Un Template Method è un modo di garantire un comportamento comune.

Le operazioni elementari sono delegate alle sottoclassi.

AbstractClass

templateMethod( )primitiveOperation1( )primitiveOperation2( )

ConcreteClass

primitiveOperation1( )primitiveOperation2( )

. . .primitiveOperation1();. . .primitiveOperation2();. . .

Page 13: L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.

L.Lista, V. Innocente

VisitorVisitor

Visitor

visit1 (ConcreteElement1)visit2 (ConcreteElement2)

ConcreteVisitor1

visit1 (ConcreteElement1)visit2 (ConcreteElement2)

ConcreteVisitor2

visit1 (ConcreteElement1)visit2 (ConcreteElement2)

Element

accept (Visitor)

ConcreteElement1

accept (Visitor v)

ConcreteElement2

accept (Visitor v)

Client

v->visit1(this) v->visit2(this)

Permette di aggiungere nuove operazioni a Element senza modificarne l’interfaccia.

Per aggiungere nuovi ConcreteElement, bisogna modificare tutti i Visitors.