Design
Patterns
Luca Lista, Vincenzo Innocente
L.Lista, V. Innocente
Design Patterns
E. Gamma et al., Design 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
L.Lista, V. Innocente
Factory
Client
Factory
createProduct1 () : AbstractProduct
createProduct2 () : AbstractProduct
AbstractProduct
I client possono
richiedere la creazione
di un prodotto senza
dipendervi.
La Factory dipende
dai prodotti concreti,
mentre i client
dipendono solo
AbstractProduct.
ConcreteProduct1
L.Lista, V. Innocente
ConcreteProduct2
Singleton
_instance : Singleton
instance () : Singleton
specificService ()
Singleton
if (_instance==0)
_instance = new Singleton();
return _instance;
user_code()
{
Singleton::instance()->specificService(...);
}
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.
L.Lista, V. Innocente
Singleton
_ins tanceT : T
ins tance () : T
Singleton{V}
V
V( )
s pecificService( )
Template Singleton
if (_ins tance==0)
_ins tance = new T();
return _ins tance;
class V : public Singleton<V>
{
public:
specificService(...);
private:
V();
friend class Singleton<V>;
};
user_code()
{
V::instance()->specificService(...);
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…).
L.Lista, V. Innocente
Proxy
Subject
Client
reques t( )
Proxy
RealSubject
_sub ject
_s ubject : RealSubject
reques t( )
1
Una richiesta da un client a un server, può essere
mediata dal Proxy, che può compiere anche altre
operazioni (I/O, caching, etc.)
L.Lista, V. Innocente
reques t( )
...
_s ubject->reques t();
...
Composite
Client
Il client può trattare
componenti e compositi
usando la stessa
interfaccia. La
composizione può essere
recursiva.
Com ponent
operation( )
1..*
_children
Com pos ite
operation( )
for c in all _children
c->operation();
Leaf
operation( )
Esempio: programmi di
grafica vettoriale
L.Lista, V. Innocente
Composite Shape
Client
Nel nostro esempio di
grafica con Shapes un
gruppo può essere
considerato un composito
e le varie classi concrete
sono le leaves.
Shape
draw( )
1..*
_children
Gruppo
draw( )
Cerchio, Rettangolo, ...
draw( )
for c in all _children
c->draw();
L.Lista, V. Innocente
Collection e Iterator
Collection
_elements : Element
Iterator
friend
append (Element)
remove (Element)
... ()
rew ind ()
next () : Element*
more () : bool
1
_elements
0..n
Un iteratore permette più
iterazioni indipendenti sulla stessa
collezione. Questo sarebbe stato
impossibile se l’iterazione fosse stato un
servizio della collezione.
Element
Oggi, sia Collection che Iterator sono implementati come
template classes (collezione “non intrusiva”).
L.Lista, V. Innocente
Strategy
Il pattern Strategy permette di scegliere
l’algoritmo da eseguire a run-time.
{
...
Strategy* s ;
s ->doAlgorithm();
...
Nuovi algoritmi possono essere introdotti
senza modificare i client.
}
Strategy
Client
doAlgorithm( )
ConcreteStrategyA
doAlgorithm( )
ConcreteStrategyB
doAlgorithm( )
L.Lista, V. Innocente
ConcreteStrategyC
doAlgorithm( )
Observer
Subject
Observer
_ob servers
update( )
_observers : Observer
attach (Observer)
notify ()
0..*
for all o in _
observables
o->update();
ConcreteObserver
ConcreteSubject
_status : Status
status( )
return _status;
_sub ject
Lo stato dell’Observer dipende
dallo stato del Subject.
Il Subject notifica a tutti gli
Observer registrati che il suo
stato è cambiato.
L.Lista, V. Innocente
_status : Status
_subject . ConcreteSubject
update( )
_status =
_subject->status();
Template Method
AbstractClass
tem plateMethod( )
primitiveOperation1( )
primitiveOperation2( )
...
primitiveOperation1();
...
primitiveOperation2();
...
Un Template Method è un modo di
garantire un comportamento comune.
ConcreteClass
primitiveOperation1( )
primitiveOperation2( )
Le operazioni elementari sono delegate
alle sottoclassi.
L.Lista, V. Innocente
Visitor
Client
Vis itor
vis it1 (ConcreteElem ent1)
vis it2 (ConcreteElem ent2)
Elem ent
accept (Vis itor)
ConcreteVisitor1
vis it1 (ConcreteElem ent1)
vis it2 (ConcreteElem ent2)
ConcreteElem ent1
ConcreteElem ent2
accept (Vis itor v)
accept (Vis itor v)
v->vis it1(this )
v->vis it2(this )
ConcreteVisitor2
vis it1 (ConcreteElem ent1)
vis it2 (ConcreteElem ent2)
Permette di aggiungere nuove operazioni a
Element senza modificarne l’interfaccia.
Per aggiungere nuovi ConcreteElement,
bisogna modificare tutti i Visitors.
L.Lista, V. Innocente
Scarica

Singleton