Objet composite

Objet composite

En génie logiciel, un objet composite est un patron de conception (design pattern) structurel. Ce patron permet de concevoir une structure d'arbre, comme par exemple un arbre binaire en limitant à 2 le nombre de sous-éléments.

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

  • Composant
    • est l'abstraction pour tous les composants, y compris ceux qui sont composés
    • déclare l'interface pour le comportement par défaut
  • Feuille
    • représente un composant n'ayant pas de sous-éléments
    • implémente le comportement par défaut
  • Composite
    • représente un composant pouvant avoir des sous-éléments
    • stocke des composants enfants et permet d'y accéder
    • implémente un comportement en utilisant les enfants
  • Client
    • manipule les objets de la composition à travers la classe 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;
      std::for_each(files.begin(),files.end(),std::mem_fun(&Composant::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.
    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 trois 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 Display() correspond à la méthode opération() du diagramme de classes.

abstract class Component
{
    public string Name { get; set; }
 
    public abstract void Display(int indentLevel = 0);
 
    protected void Indent(int level)
    {
        for(var i = 0; i < level; i++)
            Console.Write("    ");
    }
}
 
class Leaf : Component
{
    public Leaf() { }
    public Leaf(string name) 
    { 
        this.Name = name; 
    }
 
    public override void Display(int indentLevel = 0)
    {
        this.Indent(indentLevel);
        Console.WriteLine("Leaf : {0}", this.Name);
    }
}
 
class Composite : Component
{
    public IList<Component> SubComponents { get; set; }
 
    public Composite() { }
    public Composite(string name, params Component[] subComponents) 
    { 
        this.Name = name; 
        this.SubComponents = new List<Component>(subComponents); 
    }
 
    public override void Display(int indentLevel = 0)
    {
        this.Indent(indentLevel);
        Console.WriteLine("Composite : {0}", this.Name);
 
        foreach(Component subComponent in this.SubComponents)
            subComponent.Display(indentLevel + 1);
    }
}
 
class Program
{
    static void Main(string[] args)
    {
        // Exemple d'instanciation d'une structure composite:
        Component cadre = new Composite()
        {
            Name = "fond d écran",
            SubComponents = new Component[] {
                new Composite() {  
                    Name = "ciel", 
                    SubComponents = new Component[] { 
                        new Leaf() { Name="soleil" }}},
                new Composite() {  
                    Name = "mer",
                    SubComponents = new Component[] {
                        new Leaf() { Name = "bouée" },
                        new Composite() { 
                            Name="bateau", 
                            SubComponents = new Component[] {
                                new Leaf() { Name="kevin" },
                                new Leaf() { Name="katsumi" }}}}}}};
 
 
        // Et voilà le pourquoi de l'utilisation du pattern:
        //     un seul appel à Display dessine tout le cadre.
        cadre.Display();
 
        // Le même cadre défini de façon alternative via les constructeurs:
        Component cadre2 = new Composite("fond d écran",
            new Composite("ciel",
                new Leaf("soleil")),
            new Composite("mer",
                new Leaf("bouée"),
                new Composite("bateau", 
                    new Leaf("kevin"),
                    new Leaf("katsumi"))));
 
        // Et on obtient le même résultat:
        cadre2.Display();
 
        Console.ReadLine();
    }
}

Et le résultat (en double):

Composite : fond d écran
    Composite : ciel
        Leaf : soleil
    Composite : mer
        Leaf : bouée
        Composite : bateau
            Leaf : kevin
            Leaf : katsumi

Wikimedia Foundation. 2010.

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

Игры ⚽ Поможем решить контрольную работу

Regardez d'autres dictionnaires:

  • Composite (Motif de conception) — Objet composite En génie logiciel, un objet composite est un patron de conception (design pattern) structurel. Sommaire 1 Motivation 2 Quand l utiliser 3 Structures 4 …   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

  • Objet Geometries — Type Private Industry Rapid prototyping Genre 3D printing …   Wikipedia

  • Objet (informatique) — Pour les articles homonymes, voir Objet. En informatique, un objet est un conteneur symbolique, qui possède sa propre existence et incorpore des informations et des mécanismes[1] en rapport avec une chose tangible du monde réel manipulée dans un… …   Wikipédia en Français

  • Diagramme de structure composite — Dans le langage UML, le diagramme de structure composite expose la structure interne d une classe ainsi que les collaborations que cette dernière rend possible. Les éléments de ce diagramme sont les parties (en anglais parts), les ports par le… …   Wikipédia en Français

  • Canne (objet) — Canne (marche) Pour les articles homonymes, voir Canne. La canne est le nom générique d un accessoire allongé en forme de bâton, touchant le sol et tenu à la main, principalement destiné à aider la marche, bien qu il puisse remplir d autres… …   Wikipédia en Français

  • Méthode d'analyse et de conception d'applications orientées objet — Pour les articles homonymes, voir MACAO. La méthode d analyse et de conception d applications orientées objet (dite MACAO) est fondée sur une démarche participative par prototypage incrémental (processus itératif) permettant aux utilisateurs d… …   Wikipédia en Français

  • ART - L’objet culturel — Une lecture attentive des œuvres d’art nous montre que la figuration, loin d’être l’approximation toujours menacée d’un «réalisme» trop généralement valorisé, est une expression complexe de l’ordre social; elle obéit plus généralement à une… …   Encyclopédie Universelle

  • Application Composite — Pour les articles homonymes, voir Mashup. Une application composite (ou mashup ou encore mash up) est une application qui combine du contenu ou du service provenant de plusieurs applications plus ou moins hétérogènes. On parle de mashup dans le… …   Wikipédia en Français

  • Interface (programmation orientée objet) — Pour les articles homonymes, voir Interface (homonymie). En programmation orientée objet, une interface est l ensemble des méthodes publiques d un objet. De l extérieur de la classe, on ne modifie l objet que par l intermédiaire de son interface …   Wikipédia en Français

Share the article and excerpts

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