4. Design Pattern Strutturali
✦ Riguardano il modo in cui più oggetti
sono collegati tra di loro per formare
strutture complesse
✦ Usano l’ereditarietà e il polimorfismo per
comporre interfacce diverse o
implementazioni diverse di una stessa
interfaccia
4
5. Adapter (class)
✦ Il problema
• occorre utilizzare una classe già disponibile
(Adaptee) insieme a una libreria di classi
sviluppata in maniera indipendente; la libreria
richiede una particolare interfaccia (Target) che
non è presente nell’Adaptee
5
6. Adapter (class)
✦ Soluzione
• Si crea una nuova classe (Adapter) che
implementa l’interfaccia Target ed eredita
l’implementazione della classe Adaptee
• L’implementazione nell’Adapter dei metodi di
Target richiama i metodi di Adaptee
6
8. Adapter (class)
✦ Conseguenze
• se Target non è un’interfaccia pura (“interface” in
Java), è necessaria l’ereditarietà multipla (non
presente in tutti i linguaggi)
• PROBLEMA: un Adapter adatta un singolo
Adaptee; se c’è una gerarchia di Adaptee occorre
realizzare una gerarchia parallela di Adapter
• viene creato un unico oggetto che funge sia da
Adaptee che da Target (basso overhead a tempo
di esecuzione)
• PROBLEMA: complicata la situazione in cui un
Adaptee deve essere adattato a diversi Target
8
9. Adapter (object)
✦ Il problema
• occorre utilizzare una classe già disponibile
(Adaptee) insieme a una libreria di classi sviluppata
in maniera indipendente; la libreria richiede una
particolare interfaccia (Target) che non è presente
nell’Adaptee
9
10. Adapter (object)
✦ Soluzione
• Si crea una nuova classe (Adapter) che implementa
l’interfaccia Target e contiene un riferimento a un
oggetto della classe Adaptee (tipicamente passato al
costruttore)
• L’implementazione nell’Adapter dei metodi di Target
richiama i metodi dell’oggetto Adaptee
10
12. Adapter (object)
✦ Conseguenze
• l’Adapter può essere utilizzato per oggetti della
classe Adaptee e di tutte le classi derivate
• se necessario, è possibile cambiare a run time
l’oggetto Adaptee associato a un Adapter
• uno stesso oggetto Adaptee può essere associato
a diversi Adapter per Target diversi
• PROBLEMA: l’Adapter e l’Adaptee rimangono due
oggetti distinti; questo comporta un overhead di
memoria
12
14. Adapter (object)
✦ Soluzione (variante)
• in linguaggi come Java, l’Adapter può essere
realizzato come classe interna (eventualmente
anonima) dell’Adaptee
‣ in questo modo l’Adapter ha accesso a tutte le componenti
private della classe Adaptee
‣ potrebbe richiedere una modifica/estensione della classe
Adaptee, quindi si tratta di una soluzione ibrida tra Class
Adapter e Object Adapter
‣ si evita di aggiungere nuove classi visibili all’esterno
14
15. Adapter (object)
✦ Esempio
• Gestione degli eventi in Java 1.1 e successivi (es.
ActionListener, MouseAdapter etc.)
‣ per associare un’azione a un evento, tipicamente si crea un
object adapter (usando una classe anonima) che
implementa i metodi dell’interfaccia Listener appropriata
richiamando metodi dell’oggetto che effettivamente
eseguirà l’azione
15
16. Composite
✦ Il problema
• il sistema deve gestire oggetti (Component) che
possono essere sia oggetti semplici che oggetti
complessi composti da più oggetti semplici
(eventualmente in maniera gerarchica)
• si vuole rendere il client che usa questi oggetti
indipendente dal fatto che stia manipolando un
componente semplice o un oggetto composto
16
17. Composite
✦ Soluzione
• Si definisce una classe Composite che implementa
l’interfaccia di Component, e mantiene al suo
interno una collezione di Component
• il Composite implementa i metodi di Component
invocando a sua volta i metodi dei componenti da
cui è costituito
17
19. Composite
✦ Conseguenze
• semplifica il client (nascondendo la differenza tra
componenti semplici e composti)
• rende più semplice l’aggiunta di nuovi tipi di
componenti
• PROBLEMA: non è facile porre dei vincoli sulla
composizione (es. un oggetto può contenere solo
componenti di un certo tipo)
19
21. Composite
✦ Esempio
• la gerarchia di componenti grafici in AWT
‣ ogni componente grafico deriva da java.awt.Component
‣ la classe java.awt.Container definisce un Component che
può contenere altri componenti (es. Window)
21