mercredi 21 avril 2010

Design Pattern Composite


Le pattern Composite est constitué d’objets ayant le même comportement sur une profondeur variable. Cela permet d’interagir sans avoir à connaître si on parle à un objet métier ou à un groupe.

Description du problème

Lorsque l’on travaille avec des données sous forme d’arbre, il est souvent nécessaire de différencier les branches des feuilles pour savoir quel traitement effectuer.

Pour illustrer le contexte, prenons un exemple :
Nous souhaitons faire une application de dessin qui manipule des objets « graphiques » de base (carré, cercle, triangle,...). L’utilisateur lui a besoin de formes plus complexes qui seront fait à partir de formes de base ou même d’assemblage d’autres formes complexes. Il est donc nécessaire que ces formes complexes se comportent de la même façon qu’une forme simple.

Si on utilise un arbre simple, la programmation devient compliquée car il faut parcourir entièrement cet arbre tout en différenciant les actions réalisées sur les branches et les actions réalisées sur les feuilles. Cela nécessite du code et généralement des méthodes récursives pour effectuer les opérations.

Ce pattern répond à ce type de problème.

Diagramme UML


Définition de la solution

Composant : C’est la classe abstraite pour tous les composants, y compris les Composés. Elle déclare les interfaces pour les « opérations » et définit les méthodes de manipulation des enfants.
Feuille : Représente les « feuilles » dans la composition. Elle met en œuvre toutes les méthodes « opération ».
Composé : Elle représente un composant composite (Pouvant avoir des enfants), elle implémente les méthodes pour la manipulation des enfants (ajout, suppression,…) ainsi que les méthodes « opérations »

Le pattern Composite permet au client de ne pas avoir à se soucier s’il interagi avec une feuille ou une branche (Composé).

Le composé s’occupera lui même de transmettre les demandes aux feuilles. On pourra même rajouter de l’intelligence au niveau de la branche.

Dans notre exemple, on pourrait très bien imaginer un calcul de volume : chaque feuille calcule son volume et le composé additionne tous ces volumes.

Le client exécute une « opération » sur un composé. Ce composé exécute un prétraitement (si besoin), parcoure tous ces fils en demandant l’exécution de la même opération, puis fait un post-traitement (si nécessaire).

Variante

L’élément « composant » peut être une simple interface. Mais alors il faut implémenter dans chaque feuille les méthodes pour la manipulation des fils.

Conséquences

L’arbre ainsi réalisé est fortement typé. Il ne peut donc pas être utilisé de façon générique mais facilite fortement le développement du « Client ».

L’interaction entre les branches et les feuilles en est aussi simplifié; les branches ne s’occupant que de retransmettre les ordres aux feuilles sans avoir à connaître leur comportement interne.

Ce design-paterne ne doit être utilisé que si les feuilles et les branches ont des opérations communes (déclaré dans la classe composant).

Exemple

Aucun commentaire :

Enregistrer un commentaire