Le design pattern Composite
Description
Le but du design pattern Composite est de matérialiser des compositions d’objets sous la forme d’une structure arborescente. Ces compositions sont conçues de telle façon qu’un client traitera indifféremment un composant et un composé.
Exemple
Au sein de notre système de vente de véhicules, nous voulons représenter les sociétés clientes, notamment pour connaître le nombre de véhicules dont elles disposent et leur proposer des offres de maintenance de leur parc.
Les sociétés qui possèdent des filiales demandent des offres de maintenance qui prennent en compte le parc de véhicules de leurs filiales.
Une solution immédiate consiste à traiter différemment les sociétés sans filiales et celles en possédant. Cependant, cette différence de traitement entre les deux types de société rendrait l’application plus complexe et complètement dépendante de la composition interne des sociétés clientes.
Le design pattern Composite résout ce problème en unifiant l’interface des deux types de société et en utilisant la composition récursive. Cette composition récursive est nécessaire car une société peut posséder des filiales qui possèdent elles-mêmes d’autres filiales. Il s’agit d’une composition arborescente comme illustrée à la figure 12.1 où les sociétés mères sont placées au-dessus de leurs filiales. Pour d’évidentes raisons de simplification, nous faisons l’hypothèse...
Structure
1. Diagramme de classes
La figure 12.3 détaille la structure générique du design pattern Composite.
Figure 12.3 - Structure du design pattern Composite
2. Participants
Les participants au design pattern Composite sont les suivants :
-
Composant (AbstractSociete) est la classe abstraite qui décrit l’interface des objets de la composition, implémente les méthodes communes et introduit la signature des méthodes qui gèrent la composition en ajoutant ou en supprimant des composants.
-
Feuille (SocieteSansFiliale) est la classe concrète qui représente les feuilles de l’arbre de composition (dans une structure arborescente, une feuille ne possède pas de composants, c’est un nœud terminal).
-
Compose (SocieteMere) est la classe concrète qui décrit les objets composés de la hiérarchie. Cette classe possède une association d’agrégation avec la classe Composant.
-
Client est la classe des objets qui accèdent aux objets de la composition et les manipulent.
3. Collaborations
Les clients envoient leurs requêtes aux composants au travers de l’interface de la classe Composant.
Lorsqu’un composant reçoit une requête, il réagit en fonction de sa classe. Si le composant est une feuille, il traite la requête comme illustré à la figure 12.4.
Figure 12.4 - Traitement d’un...
Domaines d’application
Le design pattern Composite est utilisé dans les cas suivants :
-
Il est nécessaire de représenter au sein d’un système des hiérarchies de composition.
-
Les clients d’une composition doivent ignorer s’ils communiquent avec des objets composés ou non.
Exemple en PHP
Nous reprenons l’exemple des sociétés et de la gestion de leur parc de véhicules.
La classe abstraite AbstractSociete est décrite ci-après. Il convient de noter que la méthode ajouteFiliale renvoie un résultat booléen qui indique si l’ajout a pu ou non être réalisé.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Composite;
abstract class AbstractSociete
{
protected static float $coutUnitVehicule = 5;
protected int $nbrVehicules = 0;
public function ajouteVehicule(): void
{
$this->nbrVehicules++;
}
abstract public function calculeCoutEntretien(): float;
abstract public function ajouteFiliale(AbstractSociete
$filiale): bool;
}
Le code source de la classe SocieteSansFiliale est fourni à la suite. Les instances de cette classe ne peuvent logiquement pas ajouter de filiales.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Composite;
class SocieteSansFiliale extends AbstractSociete
{
public function ajouteFiliale(AbstractSociete $filiale): bool
{
return...