Pattern G.R.A.S.P Faible couplage

Problème initial

Comment réduire l’impact d’un changement d’une classe sur les autres classes ?

Solution associée

Affecter une responsabilité limitée à chaque objet de manière à éviter trop de modification en cas de changements.

Définition

Le couplage exprime la relation étroite qu'un élément (classe) entretien avec un ou des autres éléments. Un élément faiblement couplé ne possède pas ou peu de dépendances vis à vis de ces autres éléments.

Un couplage trop fort entre deux éléments peut entraîner lors de la modification d'un de ses éléments une modification d'un élément lié, ou bien une compréhension plus difficile des éléments pris séparément, ou encore une réutilisation contraignante du fait de la quantité d'éléments à intégrer pour en utiliser un seul.

Bien entendu, il ne faut pas tomber dans le piège de décider de concevoir des éléments tous indépendant et faiblement couplés, car ceci irait à l'encontre du paradigme objet définissant un système objet comme un ensemble d'objets connectés les uns aux autres et communiquant entre eux.

Un système abusivement faiblement couplé sera peu cohésif avec de nombreuses similitudes internes et des éléments de dimensions importantes.

Exemple

Soit les trois classes suivantes avec leurs spécifications :
  • Facture : Contient un ensemble de produit facturé et est associée à un mode de paiement,
  • MoyenDePaiement : Décrit un mode de paiement (espèces, chèque, carte bancaire, à crédit, ...),
  • Client : Paye les factures.
On cherche à ajouter la méthode payer() qui permet de payer une/des facture(s) à l’aide d’un moyen de paiement dont le type est passé en paramètre. Selon le moyen de Paiement on imagine que le total d’une facture change à cause des frais supplémentaires. Deux solutions s’offrent à nous :

1ère solution :



Dans cette première solution, le client, en payant, créé une instance de MoyenDePaiement puis l’assigne à l’objet Facture et enfin réalise le paiement de la dite facture avec le moyen de paiement ajouté.

2ème solution :



Dans cette deuxième solution la méthode payer() délègue l’action de créé une instance de MoyenDePaiement à la classe Facture. Ainsi la classe Client se contente simplement d’appeler la méthode getTotal() qui lui retourne la somme à payer.

Quelle est la meilleure solution et pourquoi ?

C’est la seconde solution car c’est elle qui respecte le mieux le principe de faible couplage. En effet dans la 1ère solution la classe Client est obligée de savoir qu’il existe une classe MoyenDePaiement tout comme la classe Facture. Tandis que dans la seconde solution la classe Client délègue la responsabilité de création du moyen de Paiement à la classe Facture.

Ainsi si l’on modifie la classe MoyenDePaiement dans la 1ère solution les classes Client et Facture se trouvent affectées tandis que dans la 2ème solution seule la classe Facture sera affectée car la classe Client ne sait pas qu’il existe la classe MoyenDePaiement.

A retenir

Comme on a pu le voir dans l’exemple tout est une question de nombre de relation qu’à une classe avec une autre. Ainsi on remarque qu’en appliquant correctement les deux premiers patterns vus (Expert et Créateur) on obtient naturellement un faible couplage cohérent. De manière à évaluer le couplage d’une classe avec les autres classes on peut se poser la question suivante :
  • Combien de classes dépendent de l’existence de cette classe ?
  • Ou bien encore, si je supprime cette classe cela affecte quelle(s) classe(s) ?