1. Lezione 21: Design
Pattern Creazionali
Corso di Ingegneria del Software
Laurea Magistrale in Ing. Informatica
Università degli Studi di Salerno
1
2. Outline
✦ Introduzione ai Design Patterns
✦ I Design Patterns di creazione
• Factory Method
• Abstract Factory
• Singleton
2
3. Il termine “pattern”
pattern
noun
1 a repeated decorative design : a neat blue herringbone pattern.
• an arrangement or sequence regularly found in comparable objects or events : the
house had been built on the usual pattern.
• a regular and intelligible form or sequence discernible in certain actions or
situations : a complicating factor is the change in working patterns.
2 a model or design used as a guide in needlework and other crafts. See note at
model .
• a set of instructions to be followed in making a sewn or knitted item.
• a wooden or metal model from which a mold is made for a casting.
• an example for others to follow : he set the pattern for subsequent study.
• a sample of cloth or wallpaper.
3
4. Design Patterns: storia
✦ Il concetto è stato introdotto
dall’architetto C. Alexander nel contesto
della progettazione urbanistica e
architettonica (1975)
✦ A partire dal 1987 K. Beck e W.
Cunningham hanno applicato questa idea
alla progettazione del software
✦ La popolarità è arrivata grazie al libro
“Design Patterns” di Gamma, Helm,
Johnson, Vlissides (1994)
4
5. Design Patterns: definizione
✦ Design Pattern: soluzione progettuale per
un problema ricorrente in un determinato
contesto
• riuso dell’esperienza di progettazione (propria o
altrui)
• linguaggio comune per comunicare scelte
progettuali (se i patterns sono opportunamente
codificati e identificati)
5
6. Elementi essenziali
✦ Nome
• un Design Pattern deve essere identificato in
modo univoco per favorire la comunicazione
✦ Problema affrontato
• descrizione del contesto in cui è possibile
applicare il Pattern
✦ Soluzione
• per la progettazione OO è espressa in termini di
classi, responsabilità e collaborazioni
✦ Conseguenze
• risultati dell’applicazione del pattern (pro e
contro), da valutare nella scelta tra più alternative
6
7. Classificazione
✦ Gamma et al. descrivono i Design Pattern
classificandoli in base a due
caratteristiche:
• purpose: campo di applicazione del pattern
(Pattern di Creazione, Strutturali e
Comportamentali)
• scope: indica se il pattern specifica relazioni tra
classi oppure tra oggetti
7
9. Pattern di creazione
✦ Un creational pattern rende i componenti
del sistema che usano determinati oggetti
indipendenti da come tali oggetti siano
creati, composti e rappresentati
• nasconde (nel senso di information hiding) la
conoscenza di quali sono le classi concrete
effettivamente instanziate
• nasconde dettagli sulla creazione e sulla
composizione degli oggetti (es. parametri usati al
momento della creazione)
• riduce l’accoppiamento e aumenta la flessibilità
9
10. Factory Method
✦ Il problema
• una classe ha bisogno di creare un oggetto
(“prodotto”) che implementa un’interfaccia, ma si
vuole evitare che dipenda da una specifica
implementazione concreta tra quelle disponibili
• oppure, una classe vuole delegare alle sottoclassi
la creazione di determinati oggetti
10
11. Factory Method
✦ Soluzione
• si incapsula la creazione degli oggetti in un
metodo
• varianti
‣ il metodo può essere nella stessa classe che deve usare gli
oggetti oppure essere un metodo “static” di una classe
diversa
‣ il metodo può essere “abstract”, e quindi richiedere che
una sottoclasse ne definisca l’implementazione, oppure
essere concreto, e fornire un’implementazione di default
(ad esempio basata su configurazione esterna)
11
13. Factory Method
✦ Conseguenze
• le sottoclassi hanno “agganci” (hooks) per
estendere il comportamento della classe base
cambiando il tipo di prodotto che viene creato
• è possibile stabilire legami tra gerarchie di classi
parallele
13
14. Factory Method
✦ Esempio
• creazione di una connessione a un database con
JDBC:
‣ Connection conn=DriverManager.getConnection(...);
‣ in questo modo la creazione è indipendente dalla effettiva
classe che realizza l’interfaccia Connection (che dipende
dal driver usato)
✦ Esempio
• creazione di un iteratore per una collezione
‣ Iterator iter=myCollection.iterator();
‣ collega la gerarchia delle collezioni alla gerarchia degli
iteratori, selezionando l’iteratore appropriato per ogni
collezione concreta
14
15. Abstract Factory
✦ Il problema
• una classe ha bisogno di creare una serie di
oggetti (“prodotti”) che implementano delle
interfacce correlate, ma si vuole evitare che
dipenda da una specifica implementazione
concreta tra quelle disponibili
• il sistema deve essere configurato con famiglie
multiple di prodotti, dove una famiglia è
progettata per essere usata nel suo insieme
• si vuole distribuire una libreria di prodotti
rivelando solo le interfacce, e non le classi
concrete che le implementano
15
16. Abstract Factory
✦ Soluzione
• Si definisce un’interfaccia AbstractFactory con
metodi per creare i diversi prodotti, e una o più
classi concrete che implementano questa
interfaccia in riferimento a una singola famiglia di
prodotti
• a run-time si costruisce un’istanza di una
“concrete factory” che viene usata per creare i
prodotti
‣ NOTA: la creazione di questa istanza può essere a sua
volta realizzata con un Factory Method
16
18. Abstract Factory
✦ Conseguenze
• nasconde le classi concrete; solo la factory sa
quale classe concreta viene istanziata
• consente di sostituire facilmente una famiglia di
prodotti con un’altra
• garantisce che i prodotti usati insieme siano della
stessa famiglia
• PROBLEMA: rende onerosa l’aggiunta di nuovi
prodotti a una famiglia, in quanto bisogna
modificare simultaneamente tutte le famiglie e
tutte le “concrete factories”
18
19. Abstract Factory
✦ Esempio
• la libreria AWT ha bisogno di creare, per ogni
componente (es. finestra, menù, bottone etc.), un
oggetto (“peer”) dipendente dalla specifica
piattaforma che colleghi il componente astratto al
suo equivalente nel sistema operativo
• per ogni sistema operativo c’è una famiglia di
peer, che deve essere usata nel suo insieme;
l’effettiva famiglia usata deve essere però
nascosta al codice che usa AWT
19
20. Abstract Factory
✦ Esempio (continua)
• soluzione: la classe astratta java.awt.Toolkit
realizza una Abstract Factory:
‣ metodi createWindow, createMenu, createScrollbar,
createImage etc. per creare ciascun tipo di peer
• un’istanza di una sottoclasse concreta di Toolkit
viene creata con un Factory Method:
‣ Toolkit tk = Toolkit.getDefaultToolkit();
• la scelta della concrete factory viene fatta in base
alla configurazione della Java Virtual Machine
20
21. Singleton
✦ Il problema
• in alcuni casi è necessario garantire che una
classe abbia un’unica istanza, accessibile
attraverso un unico punto di accesso
‣ NOTA: tipicamente questo si verifica quando la classe
mantiene informazioni di stato che devono essere
condivise da più parti del programma, e non è corretto
oppure non è efficiente (ad es. nel caso di una cache) che
queste informazioni siano duplicate
‣ NOTA: spesso questa proprietà è desiderabile per le
Abstract Factories
21
22. Singleton
✦ Soluzione
• si rende il costruttore della classe privato, in
modo che non sia possibile creare direttamente
istanze (al di fuori del codice della classe)
• si fornisce un metodo “static” per ottenere l’unica
istanza, che viene conservata in un campo static
privato della classe
• variazioni
‣ l’istanza può essere creata all’inizializzazione del
programma, oppure la prima volta che viene richiesta
‣ l’istanza, se necessario, può appartenere a una sottoclasse
della classe singleton (vedi Factory Method)
22
24. Singleton
✦ Conseguenze
• accesso controllato all’unica istanza
• non occorre introdurre variabili globali per
accedere all’unica istanza
• è semplice estendere (attraverso subclassing) la
classe singleton senza modificare il codice che la
usa
• se necessario, è semplice passare da una singola
istanza a un numero diverso di istanze
24
25. Singleton
✦ Esempio di implementazione
import java.util.*;
public class Cache {
static private Cache instance=null;
public static Cache getCache() {
if (instance==null)
instance=new Cache();
return instance;
}
private Map<String, String> map;
private Cache() {
map=new HashMap<String, String>();
}
public String get(String key) {
return map.get(key);
}
public void put(String key, String value) {
map.put(key, value);
}
}
25
26. Singleton
✦ Esempio
• Nella libreria AWT vers. 1.6 c’è una classe
SystemTray che rappresenta quella parte del
desktop nota come “system tray”, “taskbar status
area” ecc. Poiché sul desktop ci può essere un
solo system tray, la classe è gestita come
Singleton
‣ ...
SystemTray tray = SystemTray.getSystemTray();
tray.add(statusIcon);
...
26