Composite
Da Wikipedia, l'enciclopedia libera.
Nella programmazione ad oggetti, il Composite è uno dei pattern fondamentali, definiti originariamente dalla gang of four.
Il design pattern Composite organizza gli oggetti in una struttura ad albero, nella quale i nodi sono delle composite e le foglie sono oggetti semplici.
È utilizzato per dare la possibilità al cliente di manipolare gli oggetti in modo uniforme.
Indice |
[modifica] Struttura di una composite
- Client: manipola gli oggetti attraverso l'interfaccia Component.
- Component: dichiara l'interfaccia per gli oggetti, per l'accesso e la manipolazione di questi, imposta un comportamento di default per l'interfaccia comune a tutte le classi e può definire un'interfaccia per l'accesso al padre del componente e la implementa se è appropriata.
- Composite: definisce il comportamento per i componenti aventi figli, salva i figli e implementa le operazioni ad essi connesse nell'interfaccia Component.
- Leaf: definisce il comportamento degli oggetti primitivi, cioè delle foglie.
[modifica] Funzionamento
Attraverso l'interfaccia Component, il Client interagisce con gli oggetti della composite. Se l'oggetto desiderato è una Leaf, la richiesta è processata direttamente; altrimenti, se è una Composite, viene rimandata ai figli cercando di svolgere le operazioni prima e dopo del rimando.
In questo modo, si semplifica il Client, si creano delle gerarchie di classi, si semplifica l'aggiunta di nuovi componenti, anche se il design diventa troppo generale.
[modifica] Esempi
Il seguente esempio, scritto in Java, implementa una classe grafica che può essere sia un'ellisse o una composizione di varie figure. Ogni figura può essere stampata. In forma algebrica,
Graphic = ellipse | GraphicList
GraphicList = empty | ellipse GraphicList
Può essere estesa fino ad implementare altre forme (rettangolo, ecc.) e metodi (traslare, ecc.).
List = empty_list | atom List | List List
import java.util.List; import java.util.ArrayList; interface Graphic { //Stampa il grafico. public void print(); } class CompositeGraphic implements Graphic { //Collezione di grafici figli. private List<Graphic> mChildGraphics = new ArrayList<Graphic>(); //Stampa il grafico. public void print() { for (Graphic graphic : mChildGraphics) { graphic.print(); } } //Aggiunge il grafico alla composizione. public void add(Graphic graphic) { mChildGraphics.add(graphic); } //Rimuove il grafico dalla composizione. public void remove(Graphic graphic) { mChildGraphics.remove(graphic); } } class Ellisse implements Graphic { //Stampa il grafico. public void print() { System.out.println("Ellisse"); } } public class Program { public static void main(String[] args) { //Inizializza tre ellissi Ellisse ellisse1 = new Ellisse(); Ellisse ellisse2 = new Ellisse(); Ellisse ellisse3 = new Ellisse(); Ellisse ellisse4 = new Ellisse(); //Inizializza tre grafici composti CompositeGraphic graphic = new CompositeGraphic(); CompositeGraphic graphic1 = new CompositeGraphic(); CompositeGraphic graphic2 = new CompositeGraphic(); //Compone i grafici graphic1.add(ellisse1); graphic1.add(ellisse2); graphic1.add(ellisse3); graphic2.add(ellisse4); graphic.add(graphic1); graphic.add(graphic2); //Stampa i grafici completi (quattro volte la stringa "Ellisse"). graphic.print(); } }
Esempio C++
#include <iostream> #include <vector> using namespace std; class Component { public: virtual void traverse() = 0; }; class Primitive : public Component { int value; public: Primitive( int val ) { value = val; } void traverse() { cout « value « " "; } }; class Composite : public Component { vector<Component*> children; int value; public: Composite( int val ) { value = val; } void add( Component* c ) { children.push_back( c ); } void traverse() { cout « value « " "; for (int i=0; i < children.size(); i++) children[i]->traverse(); } }; class Row : public Composite { public: // Due diversi tipi di classi Row( int val ) : Composite( val ) { } // "container". La maggior parte del void traverse() { // codice è nella classe base Composite cout « "Row"; Composite::traverse(); } }; class Column : public Composite { public: Column( int val ) : Composite( val ) { } void traverse() { cout « "Col"; Composite::traverse(); } }; main() { Row first( 1 ); // Row1 Column second( 2 ); // | Column third( 3 ); // +-- Col2 Row fourth( 4 ); // | | Row fifth( 5 ); // | +-- 7 first.add( &second ); // +-- Col3 first.add( &third ); // | | third.add( &fourth ); // | +-- Row4 third.add( &fifth ); // | | | first.add( &Primitive( 6 ) ); // | | +-- 9 second.add( &Primitive( 7 ) ); // | +-- Row5 third.add( &Primitive( 8 ) ); // | | | fourth.add( &Primitive( 9 ) ); // | | +-- 10 fifth.add( &Primitive(10 ) ); // | +-- 8 first.traverse(); cout « '\n'; // +-- 6 }
[modifica] Voci correlate
| Design patterns nel libro Design Patterns | |
|---|---|
| Creazionali | Abstract factory · Builder · Factory · Prototype · Singleton |
| Strutturali | Adapter · Bridge · Composite · Decorator · Façade · Flyweight · Proxy |
| Comportamentali | Chain of responsibility · Command · Interpreter · Iterator · Mediator · Memento · Observer · State · Strategy · Template method · Visitor |

