Composite

Da Wikipedia, l'enciclopedia libera.

(Reindirizzamento da Composite pattern)
bussola Nota disambigua – Se stai cercando le piante della famiglia delle Compositae della classe dei dicotiledoni, vedi Asteraceae.

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

Struttura del pattern Composite
Struttura del pattern 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


Strumenti personali