2. “Once you understand the design pattern and
have had an 'Aha!' experience with them, you
won't ever think about object-oriented design
in the same way ”
Gamma, Helm, Johnson, Vlissides
3. Design Pattern
Un design pattern può essere definito come una soluzione progettuale
generale a un problema ricorrente
Serve a …
• Progettare e implementare software flessibile e capace di evolvere
• Dominare la complessità di un Sistema Software
Ogni Design Pattern ha:
• un nome
• un campo di applicabilità
• uno schema di soluzione
• una descrizione delle conseguenze della sua applicazione.
4. Storia
Termine coniato nel 1977 da Christopher Alexander
Introdotti nell'ingegneria informatica da Gamma, Helm, Johnson
e Vlissides (Gang of Four) attraverso il libro Design Patterns:
Elements of Reusable Object-Oriented Software
Si suddividono in:
• Crezionali: astraggono il processo di istanziazione
• Strutturali: si occupa della composizione degli oggetti
• Comportamentali: sgestiscono le responsabilità tra oggetti
7. Cocktail Bar
public interface Cocktail
{
double Cost {get;}
string Description {get;}
}
public class Daiquiri : Cocktail public class Mojito : Cocktail
{ {
public double Cost public double Cost
{ {
get {return 4.5;} get {return 5;}
} }
public string Description public string
{ Description
get{return "Daiquiri";} {
} get{return "Mojito";}
} }
}
8. Cocktail Bar
public class Bill
{
List<Cocktail> cocktails;
public Bill()
{
cocktails = new List<Cocktail>();
}
public void AddCocktail(Cocktail cocktail)
{
cocktails.Add(cocktail);
}
public string GenerateReport()
{
string report = "";
foreach (Cocktail cocktail in cocktails)
report += cocktail.Description + ":t" + cocktail.Cost;
report += "nTOTALE:t" + this.Calculate() + "n";
return report;
}
public double Calculate()
{
double cal = 0;
foreach (Cocktail cocktail in cocktails)
cal += cocktail.Cost;
return cal;
}
}
10. Nuove Richieste: Gli extra
Si vogliono poter aggiungere degli extra al cocktail ed in particolare:
- Absolut: aggiunta di alcol extra (+ 2 Euro)
- On the Rocks: aggiunta di ghiaccio (+ 0,5 Euro)
- Double: cocktail doppio (+ 80%)
Gli extra sono applicabili a tutti i cocktail e combinabili tra loro:
- Mojito Absolute On the Rocks
- Daiquiri Double
12. Pattern Decorator
Intento: Aggiungere responsabilità addizionali agli oggetti in maniera dinamica
Motivazione: supponiamo in una GUI di avere un oggetto di tipo TextView e vogliamo aggiungervi responsabilità come
bordi, scrollbar, ecc. Potremmo decidere di farlo tramite ereditarietà, ma in tal modo il meccanismo sarebbe statico
(il client non può controllare quando e come aggiungere un bordo). Il decorator rende l’estensione trasparente
all’interfaccia del componente che decora
Applicabilità: Il Decorator andrebbe usato:
• Per aggiungere responsabilità ad oggetti dinamicamente e trasparentemente;
• Per aggiungere responsabilità che possono essere eliminate;
• Quando l’estensione tramite subclassing si rivela poco pratica (es. un cospicuo numero di estensioni produrrebbe
un’esplosione delle sottoclassi per supportare ogni combinazione).
Struttura:
15. Nuove Richieste: Cocktail Light
Il marketing decide che gli "astemi" vanno premiati e decidono di scontare le
versioni analcoliche dei cocktail (-0,5 Euro).
Per fare questo si potrebeb creare un nuovo extra (decorator) chiamato Light
A questo punto iniziano i problemi
- I decorator cominciano ad essere tanti e di difficile gestione.
- Sorgono delle inconguenza (Absolut Light Daiquiri???).
Come Fare?
17. Pattern Factory
Intento: definire un’interfaccia per la creazione di un oggetto, delegando alle sottoclassi la decisione su quali classi
istanziare.
Motivazione: consideriamo un framework che presenta documenti multipli agli utenti. Le classi chiave sono Application
e Document, entrambe astratte. Per creare un’applicazione per disegnare, occorre creare le classi
DrawingApplication e DrawingDocument. Il pattern sposta all’esterno del framework la conoscenza di quale
sottoclasse di documenti creare.
Applicabilità: il pattern può essere utilizzato quando:
• Una classe non può conoscere in anticipo la classe di oggetti che deve creare;
• Una classe desidera che le proprie sottoclassi specifichino gli oggetti che creano;
• Una classe delega responsabilità ad una delle proprie sottoclassi, e occorre localizzare la conoscenza della classe a
cui delegare
Struttura: