Semaine 11
Activité 3
Patron de conception Composite
Le patron de conception Composite est un modèle important dans l’API Swing, qui permet notamment la délégation automatique de l’affichage des composantes graphiques aux composantes elle-même. En fait, chaque composante graphique de Swing (ex. JButton) hérite de la classe abstraite JComponent qui possède un ensemble de méthodes gérant l’affichage et le comportement de base de toutes les composantes graphiques. Or, la classe abstraite JComponent hérite elle-même de la classe Container, qui gère l’imbrication de composantes graphiques entre elles, par exemple, un JButton à l’intérieur d’un JPanel qui est lui-même à l’intérieur d’un JFrame. Ainsi, chaque interface graphique Swing correspond à une arborescence (ou arbre n-aire) de JComponent. Où la « magie » du patron de conception Composite entre en jeux est, par exemple, lors de la redimension d’un JFrame. À ce moment, les composantes graphiques, via une descente dans l’arborescence, sont manipulés successivement via les méthodes génériques. Ainsi, une modification à une composante dans l’arborescence, entraîne la modification aux composantes de la « branche ».
Ainsi, le patron de conception Composite consiste donc en la définition d’une classe abstraite possédant des opérations génériques à un groupe d’objets et qui permet la délégation d’opération aux objets eux-même par un appel en cascade. Le composite est semblable à un autre patron de conception, le chain of responsability. L’image ci-dessous présente le diagramme UML du patron de conception.
Voici le code générique Java pour implémenter ces composantes :
Interface Composant
public Interface Composant { public void operation(); }
À noter que l’interface peut être remplacé par une classe abstraite s’il y a des comportements commun à tous les types d’objets voulant être implémentés
Classe Composite
Pour représenter les noeuds pouvant avoir des Component sous-hiérarchiquement.
public class Composite implements Component { protected ArrayList<Component> components = new ArrayList<Component>(); @Override public void operation() { //À compléter } public void add(Component c) { components.add(c); } public void remove(Component c) { components.remove(c); } public ArrayList<Component> getComponents() { return components; } }
Classe Feuille ou Leaf
Pour représenter des feuilles ou bien des noeuds ne pouvant avoir des Component sous-hiérarchiquement.
public class Composite implements Component { @Override public void operation() { //À compléter } }
Exemple du patron avec une IHM
Supposons une interface graphique permettant le contrôle d’une machine industrielle. Selon l’état de la machine, certaines commandes sont accessibles d’autre ne le sont pas. Ces états peuvent être représenté de manière « surprenante » et providentielle (pour l’exemple évidemment!) par un graph acyclique (bref un arbre n-aire). Nous utiliserons donc le patron de conception Composite afin de gérer l’accès au panneau de contrôle, par l’appel de la méthode setEnabled. Voici un aperçu de cette interface graphique :
Selon l’état des JToggleButton et du JSlider, les boutons dans la sous-hiérarchie de l’arbre sont accessibles ou non. Voici le code source de cet exemple : exerciceComposite.zip