dans Design & Architecture, POO

Les raisons de préférer la composition à l’héritage

Il ne s’agit pas ici de prouver que la composition est meilleur que l’héritage mais en fait la vrai problématique se pose lorsque vous devez faire hériter une fonctionnalité à toute une hiérarchie de classe, vaut il mieux dans ce cas rajouter la  fonction dans la classe mère et en faire bénéficier toutes les sous classes ou préférer encapsuler cette fonctionnalité au travers d’une composition.

L’héritage et la composition partage une similarité elles sont utilisées toutes les deux afin d’éviter la duplication de code donc encourage la réutilisation de code qui reste parmi les bonnes pratiques de développement connu sous le nom de DRY (Dont Repeat Yourself)

Mais dans quel cas choisir l’un plutôt que l’autre?

Tout d’abord il faut rappeler qu’il n’y a pas de règle absolue, l’héritage a ses avantages tout comme la composition. Dans certains cas il est plus pertinent d’utiliser une relation d’héritage plutôt qu’une relation de composition.

Définitions

L’héritage traduit une relation de type « is-a » (est-un) alors que la composition traduit une relation de type « has-a » (a-un) ou (possede-un).

L’héritage sera utilisé lorsqu’il existe un vrai lien de similitude entre 2 classes.

Exemple entre une classe Animal et Chat ou encore entre Appareil et Téléphone ou encore Véhicule et voiture.

Un Chat est un Animal et un Téléphone est un Appareil, en définissant une telle relation on crée donc un lien fort entre la classe Chat et la classe Animal.

On partage donc des comportements et des attributs communs entre les 2 classes de même qu’entre Véhicule et voiture.

Un lien d’héritage définit de la sorte ne pose pour le moment aucun problème d’un point de vue conceptuel.

Imaginons maintenant que je souhaite ajouter une méthode à ma classe Animal  exemple : marcher,  cette classe est elle  vraiment le bon endroit ou ajouter cette méthode ? en ajoutant la méthode dans la classe mère j’en fait alors bénéficier toutes les classes filles ce qui pourrait être intéressant d’un point de vue factorisation mais en réalité  je  peux créer par la même occasion des comportements inattendus.

Exemple si j’ai une classe Poisson qui hérite de Animal j’ai donc des Poissons avec la capacité de marcher. On voit donc ici que l’héritage crée un fort couplage entre les classes en relations.

Une modification dans la classe parent peut avoir des impacts inattendus dans les classes filles.

Les classes filles peuvent accéder aux variables protected de la classe mère ce qui peut contribuer à affaiblir l’encapsulation je détaillerai ce point dans un autre billet.

L’héritage fait ainsi bénéficier a toutes une hiérarchie de classe des fonctionnalités dont elles n’ont pas toujours besoin.

Alors quelles sont les alternatives qui s’offrent à nous?

1ere solution :

Surcharger la méthode dans les classes filles.

Cette solution est très simple à implémenter mais d’un point de vue évolutif pas très pratique, il faut penser à redéfinir la méthode pour chacune des classes n’implémentant pas ce comportement. n’oubliez pas que l’objectif ici est regrouper notre code au même endroit et ne surtout pas dupliquer (DRY).

 

2e solution:

Créer une classe intermédiaire avec les animaux pouvant marcher et  autant pour ceux pouvant nager ou voler etc…?

Cette solution mieux que la précédente a également ses limites, on crée une nouvelle hiérarchie de classe avec les problèmes évoqués plus haut, peut nous amener a modifier constamment nos classes filles en cas de modification des classes parents. Il nous faut quelque chose de plus souple.

3e solution:

Utiliser des interfaces, nous pourrions créer une interface « Marchable » qu’implémenterait uniquement les animaux capable de marcher mais içi aussi le code serait dupliqué dans chacune des classes implémentant l’interface pas très pratique non plus en cas de modification.

4e solution :

Utiliser l’encapsulation , encapsuler les comportements qui sont susceptibles de varier et d’évoluer beaucoup entre les classes. Cette solution offre plusieurs avantages que nous détaillerons dans la suite de l’article.

 

 

Ecrire un Commentaire

Commenter