Objet composite

Un article de Wikipédia, l'encyclopédie libre.

En génie logiciel, un objet composite est un patron de conception (design pattern) structurel.

Sommaire

[modifier] Motivation

En programmation objet, un objet composite est constitué d'un ou de plusieurs objets similaires (ayant des fonctionnalités similaires). L'idée est de manipuler un groupe d'objets de la même façon que s'il s'agissait d'un seul objet. Les objets ainsi regroupés doivent posséder des opérations communes, c'est-à-dire un "dénominateur commun".

[modifier] Quand l'utiliser

Vous avez l'impression d'utiliser de multiples objets de la même façon, souvent avec des lignes de code identiques ou presque. Par exemple, lorsque la seule et unique différence entre deux méthodes est que l'une manipule un objet de type Carré, et l'autre un objet Cercle. Lorsque, pour le traitement considéré, la différenciation n'a pas besoin d'exister, il serait plus simple de considérer l'ensemble de ces objets comme homogène.

[modifier] Structures

  • Component (composant)
    • déclare l'interface pour la composition d'objet
    • implémente le comportement par défaut
    • déclare une interface pour l'accès aux composants enfants
  • Leaf (feuille)
    • représente des objets feuille dans la composition
  • Composite
    • définit un comportement pour les composants ayant des enfants
    • stocke les composant enfants
    • implémente la gestions des enfants de l'interface Component
  • Client
    • manipule les objets de la composition à travers l'interface Composite
La classe composant dérive "composite" et "feuille". Un composite a 0 composants ou plus.

[modifier] Exemple C++

//Cet exemple represente la hiérarchie d'un système de fichiers : fichiers/répertoires
 
 
class Composant {  
//L'objet abstrait qui sera 'composé' dans le composite
//Dans notre exemple, il s'agira d'un fichier ou d'un répertoire
  public:
    //Parcours récursif de l'arbre 
    //(Utilisez plutôt le Design Pattern "Visiteur" à la place de cette fonction)
    virtual void ls_r() = 0 ; 
 
  protected:
    std::string name;
};
 
class File : public Composant { //Leaf
  public:
    void ls_r() { std::cout << name << std::endl; }
};
 
class Repertoire : public Composant {  //Composite
//Le repertoire est aussi un 'composant' car il peut être sous-répertoire
  protected:
    std::list<Composant*> files; //List des composants
  public:
    void ls_r() { 
      std::cout << "[" << name << "]" << std::endl;
      for( std::list<Composant*>::iterator it = files.begin(); 
           it != files.end(); it ++ ) {
        it->ls_r();
      }
    }
};


L'exemple qui suit, écrit en Java, implémente une classe graphique qui peut être ou bien une ellipse ou une composition de différents graphiques. Chaque graphique peut être imprimé.

Il pourrait être étendu en implémentant d'autres formes (rectangle etc) et méthodes (translation etc).

import java.util.ArrayList;
 
interface Graphic {
 
    //Imprime le graphique.
    public void print();
 
}
 
class CompositeGraphic implements Graphic {
 
    //Collection de graphiques enfants.
    private ArrayList<Graphic> mChildGraphics = new ArrayList<Graphic>();
 
    //Imprime le graphique.
    public void print() {
        for (Graphic graphic : mChildGraphics) {
            graphic.print();
        }
    }
 
    //Ajoute le graphique à la composition composition.
    public void add(Graphic graphic) {
        mChildGraphics.add(graphic);
    }
 
    //Retire le graphique de la composition.
    public void remove(Graphic graphic) {
        mChildGraphics.remove(graphic);
    }
 
}
 
class Ellipse implements Graphic {
 
    //Imprime le graphique.
    public void print() {
        System.out.println("Ellipse");
    }
 
}
 
public class Program {
 
    public static void main(String[] args) {
        //Initialise quatre ellipses
        Ellipse ellipse1 = new Ellipse();
        Ellipse ellipse2 = new Ellipse();
        Ellipse ellipse3 = new Ellipse();
        Ellipse ellipse4 = new Ellipse();
 
        //Initialise three graphiques composites
        CompositeGraphic graphic = new CompositeGraphic();
        CompositeGraphic graphic1 = new CompositeGraphic();
        CompositeGraphic graphic2 = new CompositeGraphic();
 
        //Composes les graphiques
        graphic1.add(ellipse1);
        graphic1.add(ellipse2);
        graphic1.add(ellipse3);
 
        graphic2.add(ellipse4);
 
        graphic.add(graphic1);
        graphic.add(graphic2);
 
        //Imprime le graphique complet (quatre fois la chaîne "Ellipse").
        graphic.print();
    }
}