Il pattern decorator L21_DecoratorPattern 1
Il pattern decorator Problema affrontato: aggiungere comportamenti e caratteristiche dinamicamente ad una classe, in maniera alternativa all'ereditarietà, non attraverso interfacce, ma privilegiando la composizione. Es. Aggiungere bordi ad una finestra L21_DecoratorPattern 2
L21_DecoratorPattern 3
L21_DecoratorPattern 4
Applicabilità Usare il pattern decorator per aggiungere funzionalità agli oggetti quando l'utilizzo di interfacce o l'ereditarietà sono strade poco praticabili L21_DecoratorPattern 5
Struttura L21_DecoratorPattern 6
Esempio: scroll bar Supponiamo di avere un componente grafico "Text" cui è possibile associare un bordo semplice o 3D, ed una scroll bar verticla o orizzontale. Rappresentare tutte le combinazioni con sotto classi di TextView porta ad una moltiplicazione di classe L21_DecoratorPattern 7
Text View <- TextViewSimpleBorder TextViewSimpleBorderLeftScrollBar TextViewSimpleBorderRightScrollBar TextView3DBorder TextView3DBorderLeftScrollBar TextView3DBorderRightScrollBar Eccetera L21_DecoratorPattern 8
In questo modo, oltre ad avere una esplosione di sottoclassi, il client deve stabilire "staticamente" quale sottoclasse istanziare e non puo' certo "decorare" dinamicamente il componente L21_DecoratorPattern 9
Possibile uso del pattern Strategy public class TextView extends Component { public void draw() { // Code to draw the TextView object itself. L21_DecoratorPattern 10
Se si usa una interfaccia componet ed una superclasse Decorator, si puo' usare il pattern strategy per delegare ai componenti il meccanismo di disegno L21_DecoratorPattern 11
public class TextView extends Component { private Border border; private Scrollbar sb; public TextView(Border border, Scrollbar sb) { this.border = border; this.sb = sb; public void draw() { border.draw(); sb.draw(); // Code to draw the TextView object itself. L21_DecoratorPattern 12
Manca pero' ancora la possibilità di cambiare dinamicamente le decorazioni, ed il Text View ancora deve conoscere i suoi componenti L21_DecoratorPattern 13
Usare la composizione-> decorator pattern public class TextView extends Component { public void draw() { // Code to draw the TextView object itself. L21_DecoratorPattern 14
Adesso sono i Decorator a conoscere in cascata i vari "componenti" public class FancyBorder extends Decorator { private Component component; public FancyBorder(Component component) { this.component = component; public void draw() { component.draw(); // Code to draw the FancyBorder object itself. Uso aggiunta dei co0mponenti dinamici public class Client { public static void main(string[] args) { TextView data = new TextView(); Component borderdata = new FancyBorder(data); Component scrolleddata = new VertScrollbar(data); Component borderandscrolleddata = new HorzScrollbar(borderData); L21_DecoratorPattern 15
Uso pattern decorator I/O Un uso tipico del pattern decorator è quello relativo alle classi I/O di Java Le classi fondamentali per l'i/o sono: InputStream, OutputStream, Reader e Writer E' possibile aggiungere altre funzionalità attraverso delle classi "filter" che sono applicazioni del pattern decorator DataStream -> funzioni su tipi primitivi BufferedStream -> consente l'utilizzo di un buffer PushBackStream -> permette le operazioni "UNDO" L21_DecoratorPattern 16
public class JavaIO { public static void main(string[] args) { // Open an InputStream. FileInputStream in = new FileInputStream("test.dat"); // Create a buffered InputStream. BufferedInputStream bin = new BufferedInputStream(in); // Create a buffered, data InputStream. DataInputStream dbin = new DataInputStream(bin); // Create an unbuffered, data InputStream. DataInputStream din = new DataInputStream(in); // Create a buffered, pushback, data InputStream. PushbackInputStream pbdbin = new PushbackInputStream(dbin); L21_DecoratorPattern 17