Composite (Motif de conception)

Composite (Motif de conception)

Objet composite

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

Sommaire

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".

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.

Structures

  • Component (composant)
    • déclare l'interface pour la composition d'objet
    • met en œuvre 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 composants enfants
    • met en œuvre la gestion 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.

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();
      }
    }
};

Exemple Java

L'exemple qui suit, écrit en Java, met en œuvre 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 y ajoutant 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();
    }
}

Exemple en PHP 5

<?php
class Component
{
 
  // Attributes
  private $basePath;	
  private $name;
  private $parent;
 
  public function __construct($name, CDirectory $parent = null)
  {
    // Debug : echo "constructor Component";
    $this->name = $name;
    $this->parent = $parent;
    if($this->parent != null)
    {
       $this->parent->addChild($this);
       $this->basePath = $this->parent->getPath();
    }
    else
    {
      $this->basePath = '';			
    }
  }
 
 
  // Getters	
  public function getBasePath() { return $this->basePath; }
  public function getName() { return $this->name; }
  public function getParent() { return $this->parent; }
 
  // Setters
  public function setBasePath($basePath) { $this->basePath = $basePath; }
  public function setName($name) { $this->name = $name; }
  public function setParent(CDirectory $parent) { $this->parent = $parent; }
 
  // Method
  public function getPath() { return $this->getBasePath().'/'.$this->getName(); }
}
 
class CFile extends Component
{
 
  // Attributes
  private $type;
 
 
  public function __construct($name, $type, CDirectory $parent = null)
  {
    // Debug : echo "constructor CFile";
    $this->type = $type;
 
    // Retrieve constructor of Component
    parent::__construct($name, $parent);	
  }
 
  // Getters	
  public function getType() { return $this->type; }
 
  // Setters
  public function setType($type) { $this->type = $type; }
 
  // Methods of Component class
  public function getName() { return parent::getName().'.'.$this->getType();
  public function getPath() { return parent::getPath().'.'.$this->getType(); }
}
 
class CDirectory extends Component
{
 
  // Attributes
  private $childs;
 
  public function __construct($name, CDirectory $parent = null)
  {
    // Debug : echo "constructor CDirectory";
    $this->childs = array();
 
    // Retrieve constructor of Component
    parent::__construct($name, $parent);
  }
 
  // Getters	
  public function getChilds() { return $this->childs; }
 
  // Setters
  public function setChilds($childs) { $this->childs = $childs; }
 
 
  // Methods
  public function addChild(Component $child)
  {
    $child->setParent($this);
    $this->childs[] = $child;
  }
 
  public function showChildsTree($level = 0)
  {
    echo "<br/>".str_repeat('&nbsp;', $level).$this->getName();
    foreach($this->getChilds() as $child)
    {
      if($child instanceof self)
      {
        $child->showChildsTree($level+1);
      }
      else
      {
        echo "<br/>".str_repeat('&nbsp;', $level+1).$child->getName();
      }	
    }
  }
}
?>

Exemple d'utilisation (example of use):

<?php
$root = new CDirectory('root');
$dir1 = new CDirectory('dir1', $root);
$dir2 = new CDirectory('dir2', $root);
$dir3 = new CDirectory('dir3', $root);
$dir4 = new CDirectory('dir4', $dir2);
$file1 = new CFile('file1','txt', $dir1);
$file2 = new CFile('doc', 'pdf', $dir4);
 
$root->showChildsTree();
?>

résultat à l'écran (result on the screen) :

root
 dir1
  file1.txt
 dir2
  dir4
   doc.pdf
 dir3

Exemple C#

Produisant un résultat similaire à l'exemple en php, une variante en C#.

Dans ce code la méthode Draw() correspond à la méthode opération() du diagramme de classes.

/// <summary> Par simplicité, ni méthode Add ni Remove ni GetChild. </summary>
abstract class Composant {
    public int Level = 0;
    public string Nom; 
    public virtual void Draw() { 
        for (var i = 0; i < Level; i++)
            Console.Write("    ");
    }
}
 
class Feuille : Composant {
    public override void Draw() { 
        base.Draw();
        Console.WriteLine("Feuille : {0}", Nom);
    }
}
 
class Composite : Composant {
    public Composant[] Composants; // serait private s'il y avait une méthode Add.
    public override void Draw() {
        base.Draw();
        Console.WriteLine("Composite : {0}", Nom);
        foreach (Composant composant in Composants) {
            composant.Level = this.Level + 1;
            composant.Draw();
        }
    }
}
 
class Program {
    static void Main(string[] args) {
 
        //__________________________________________________________________________
        // On crée en général la structure par de multiples appels à la méthode Add.
 
        var cadre= new Composite() {
            Nom = "fond d écran",
            Composants = new Composant[] {
                new Composite() {  
                    Nom = "ciel", 
                    Composants = new Composant[] { 
                        new Feuille() { Nom="soleil" }}},
                new Composite() {  
                    Nom = "mer",
                    Composants = new Composant[] {
                        new Composite() { 
                            Nom="bateau", 
                            Composants = new Composant[] {
                                new Feuille() { Nom="kevin" },
                                new Feuille() { Nom="katsumi" }}}}}}
        };
 
        //__________________________________________________________________________
        // Et voilà le pourquoi de l'utilisation du pattern:
        //     un seul appel à Draw dessine tout l'écran.
 
        cadre.Draw();
    }
}

Et le résultat

Composite : fond d écran
    Composite : ciel
        Feuille : soleil
    Composite : mer
        Composite : bateau
            Feuille : kevin
            Feuille : katsumi
Ce document provient de « Objet composite ».

Wikimedia Foundation. 2010.

Contenu soumis à la licence CC-BY-SA. Source : Article Composite (Motif de conception) de Wikipédia en français (auteurs)

Игры ⚽ Нужно сделать НИР?

Regardez d'autres dictionnaires:

  • Motif de conception — Patron de conception Pour les articles homonymes, voir Patron. Un patron de conception (design pattern en anglais) est un concept de génie logiciel destiné à résoudre les problèmes récurrents suivant le paradigme objet. En français on utilise… …   Wikipédia en Français

  • Composite — Cette page d’homonymie répertorie les différents sujets et articles partageant un même nom. Sur les autres projets Wikimedia : « Composite », sur le Wiktionnaire (dictionnaire universel) Le terme composite peut se rapporter à… …   Wikipédia en Français

  • Modèle de conception — Patron de conception Pour les articles homonymes, voir Patron. Un patron de conception (design pattern en anglais) est un concept de génie logiciel destiné à résoudre les problèmes récurrents suivant le paradigme objet. En français on utilise… …   Wikipédia en Français

  • Modèles de conception — Patron de conception Pour les articles homonymes, voir Patron. Un patron de conception (design pattern en anglais) est un concept de génie logiciel destiné à résoudre les problèmes récurrents suivant le paradigme objet. En français on utilise… …   Wikipédia en Français

  • Motifs de conception — Patron de conception Pour les articles homonymes, voir Patron. Un patron de conception (design pattern en anglais) est un concept de génie logiciel destiné à résoudre les problèmes récurrents suivant le paradigme objet. En français on utilise… …   Wikipédia en Français

  • Patrons de conception — Patron de conception Pour les articles homonymes, voir Patron. Un patron de conception (design pattern en anglais) est un concept de génie logiciel destiné à résoudre les problèmes récurrents suivant le paradigme objet. En français on utilise… …   Wikipédia en Français

  • Schéma de conception — Patron de conception Pour les articles homonymes, voir Patron. Un patron de conception (design pattern en anglais) est un concept de génie logiciel destiné à résoudre les problèmes récurrents suivant le paradigme objet. En français on utilise… …   Wikipédia en Français

  • Composites — Composite Cette page d’homonymie répertorie les différents sujets et articles partageant un même nom …   Wikipédia en Français

  • Design Pattern — Patron de conception Pour les articles homonymes, voir Patron. Un patron de conception (design pattern en anglais) est un concept de génie logiciel destiné à résoudre les problèmes récurrents suivant le paradigme objet. En français on utilise… …   Wikipédia en Français

  • Design Patterns — Patron de conception Pour les articles homonymes, voir Patron. Un patron de conception (design pattern en anglais) est un concept de génie logiciel destiné à résoudre les problèmes récurrents suivant le paradigme objet. En français on utilise… …   Wikipédia en Français

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”