Sul pattern Decorator



Похожие документы
Esempio 2: Subtyping

Corso di Algoritmi e Strutture dati Programmazione Object- Oriented in Java (Parte I)

Programmazione. Cognome... Nome... Matricola... Prova scritta del 22 settembre Negli esercizi proposti si utilizzano le seguenti classi:

Programmazione. Cognome... Nome... Matricola... Prova scritta del 11 luglio 2014

Esempio: Interfacce. Gioco Interfacce

ereditarietà e polimorfismo

Riassunto: cos è la OOP? classi astratte, interfacce, classi interne. Scaletta. Figura con area()? Figura senza area()? Stefano Mizzaro 1.

Esempi al calcolatore su: 1) Costruttori ed ereditarietà 2) Subtyping e polimorfismo

Esempio: Interfacce. Gioco Interfacce

18 - Classi parzialmente definite: Classi Astratte e Interfacce

Ingegneria del Software

A. Lorenzi, A. Rizzi Java. Programmazione ad oggetti e applicazioni Android Istituto Italiano Edizioni Atlas

Overloading - Overriding

Laboratorio di Progettazione di Sistemi Software Design Patterns

Ereditarietà. Ereditarietà. Ereditarietà. Ereditarietà

Programmazione Orientata agli Oggetti in Linguaggio Java

Design Pattern Comportamentali

Esempi in Java di program.ne O-O

La classe java.lang.object

Interfacce. Esempio: interfaccia I con una sola funzione g() public interface I {

Ereditarietà e Polimorfismo

Progettazione del Software

Programmazione ad Oggetti Modulo A (Esame del 11/9/2015)

Programmazione orientata agli oggetti Classi astratte e interfacce

UML Diagrammi delle classi. UML Diagramma classi 1

Il Linguaggio Java. Le interfacce

Guida introduttiva su Eclipse. Ing. Marco Dell'Unto

Classi astratte e progettazione OOP Esempio: l enciclopedia degli animali. Esempio Animali

Funzioni, Stack e Visibilità delle Variabili in C

19 - Eccezioni. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Prefazione. Capitolo 1 Sistemi di elaborazione 1

Programmazione ad Oggetti

Транскрипт:

Sul pattern Decorator 1 Introduzione Consideriamo una famosa panineria fa tre tipi di panini: al prosciutto crudo, al prosciutto cotto, al tonno. A ciascuno di questi tre tipi corrisponde un costo. Figura 1: Schema di partenza Il programma client quando vuole un prezzo fa così: Sandwich crudo = new SandwichCrudo(); double prezzo = crudo.getcost(); Se ci sono le aggiunte (pomodoro, mozzarella, lattuga, capperi,...) ai tre tipi di base, si può avere una varietà grandissima di tipi di panino. Si ha così il modello dei Figura 2, o quello di Figura 3. Ciascun tipo di panino ha un suo specifico costo. Il modello di Figura 2 è più compatto e modulare di quello di Figura 3 ma in ogni caso si tratta di una strada impercorribile quando il numero degli ingredienti cresce. Bisogna aggiungere classi e nel definire il prezzo di un panino multiingredienti occorre fare mente locale a quanto vale il prezzo della base, ecc. Se un ingrediente viene a costare di più occorre mettere mano a tutte le classi in cui c è l ingrediente. Regola Il sistema deve essere aperto alle espansioni, ma le classi devono restare chiuse! toccando solo in un punto. Col modello di Figura 3 si avrebbe questo genere di codice. Si estende aggiungendo o Sandwich crudomozzpom = new SandwichCrudoMozzarellaPomodoro(); double prezzo = crudomozzpom.getcost(); 1

Figura 2: Panini diversificati rispetto a quelli di base in funzione degli ingredienti aggiuntivi. Figura 3: Panini diversificati in base agli ingredienti principali e agli ingredienti aggiuntivi. 2 Tenere separati gli aspetti che si possono aggiungere Conviene aggiungere il costo di ciascun ingrediente a quello di base del panino, come in Figura 4. Sandwich panino = new SandwichCrudo(); panino.addingrediente(pomo); panino.addingrediente(xx); double prezzo = panino.getcost(); forall i in panino.ingredienti prezzo = prezzo + i.getcost(); Vantaggi Si può estendere quanto si vuole. Le classi sono separate. Tutto si limita ad aggiungere nuove classi nell aggregato degli ingredienti. 2

Figura 4: Panini diversificati in base ai tre tipi principali con l aggiunta di ingredienti. 2.1 Un altro modo (migliore?): il decoratore In Figura 5 c è il modello generale del decoratore. In Figura 6 il decoratore applicato al nostro esempio. Figura 5: Pattern Decorator. 3

Figura 6: Pattern Decorator nel nostro caso. Nel caso specifico. public abstract class Sandwich{ protected double cost; public abstract double getcost(); public class SandwichCrudo extends Sandwich{ public SandwichCrudo(double cost){ this.cost = cost; public double getcost(){ return cost; public abstract class IngrDecoratore extends Sandwich{ protected Sandwich component; public class Pomodoro extends IngrDecoratore{ public Pomodoro(Sandwich component){ this.component = component; double getcost(){ return component.getcost+cost; // Nel client Sandwich panino = new SandwichCrudo(); panino = new Pomodoro(panino); panino = new Lattuga(panino); panino = new Capperi(panino); //panino di base // panino + pomodoro // panino + pomodoro + lattuga // panino + pomodoro + lattuga + capperi 4

int prezzo = panino.getcost(); Vantaggi Come sopra: si può estendere quanto si vuole. Si tratta di aggiungere classi senza toccare le esistenti Il decoratore aggiunge funzionalità a un oggetto. Si può costruire una pila di decoratori: il client può limitarsi a vedere solo il frutto dell ultima decorazione. L esempio tipico è quello delle interfacce: una finestra viene decorata con una scrollbar. Il client vede solo una finestra con scrollbar e non sa che la finestra in effetti è di per sé priva di scrollbar. Definizione Il pattern Decorator aggiunge funzionalità a un oggetto dinamicamente. La decorazione è una alternativa al subclassing (all uso dell ereditarietà per differenziare-estendere le funzionalità ). 2.1.1 Confronto con la programmazione procedurale Anche per il decoratore la base concettuale è rappresentata dal polimorfismo e dalla composizione degli oggetti a runtime. Nella programmazione procedurale ciò era possibile solo in parte. Le procedure ricorsive sono esempi di decoratori che, iterativamente, lavorano sugli ingressi prodotti da una precedente chiamata. Nella programmazione procedurale non esiste un meccanismo come quello della composizione degli oggetti e pertanto l unica possibilità è quella di prevedere sequenze di chiamate a tempo di compilazione. 3 Decoratori in Java Java fa un largo uso di decoratori nel package di io. In Figura 7 viene mostrato il decoratore FilteredInputStream e due sue realizzazioni concrete Figura 7: Sopra: alcune classi nella gerarchia di input. Sotto la gerarchia per la classe InputDataStream. 5