Skip to content

Les principes SOLID

En programmation orientée objet, SOLID est un acronyme mnémonique qui regroupe cinq principes de conception destinés à produire des architectures logicielles plus compréhensibles, flexibles et maintenables.

Bien qu'ils s'appliquent à toute conception orientée objet, les principes SOLID peuvent également former une philosophie de base pour des méthodologies telles que le développement agile ou le développement de logiciels adaptatifs.

 

Principes

Responsabilité unique (Single responsibility principle) :

Une classe, une fonction ou une méthode doit avoir une et une seule responsabilité!

Prenons l'exemple d'un module qui compile et imprime un rapport. Imaginons que ce module peut changer pour deux raisons.

D'abord, le contenu du rapport peut changer.

Ensuite, le format du rapport peut changer.

Ces deux choses changent pour des causes différentes ; l'une substantielle, et l'autre cosmétique.

Le principe de responsabilité unique dit que ces deux aspects du problème ont deux responsabilités distinctes, et devraient donc être dans des classes ou des modules séparés.

Ce serait une mauvaise conception de coupler ces deux choses dans une même classe.

La raison pour laquelle il est important de garder une classe axée sur une seule préoccupation est que cela rend la classe plus robuste. En continuant avec l'exemple précédent, s'il y a un changement dans le processus de compilation du rapport, il y a un plus grand danger que le code d'impression se casse si elle fait partie de la même classe.

  Ouvert/fermé (Open/closed principle) :

Une entité applicative (classe, fonction, module ...) doit être fermée à la modification directe mais, ouverte à l'extension.

"Ouverte" signifie qu'elle a la capacité d'être étendue.

"Fermée" signifie qu'elle ne peut être modifiée que par extension, sans modification de son code source.

L'idée est qu'une fois qu'une classe a été approuvée via des revues de code, des tests unitaires et d'autres procédures de qualification, elle ne doit plus être modifiée mais, seulement étendue.

En pratique, le principe ouvert/fermé oblige à faire bon usage de l'abstraction et du polymorphisme.

 

Substitution de Liskov (Liskov substitution principle):

Une instance de type T doit pouvoir être remplacée par une instance de type G, tel que G un sous-type de T, sans que cela modifie la cohérence du programme.

Le principe de substitution de Liskov est étroitement relié à la méthodologie de programmation par contrat aboutissant à des restrictions qui spécifient la manière dont les contrats peuvent interagir avec les mécanismes d'héritage :

  • Les préconditions ne peuvent pas être renforcées dans une sous-classe. Cela signifie que vous ne pouvez pas avoir une sous-classe avec des préconditions plus fortes que celles de sa superclasse ;
  • Les postconditions ne peuvent pas être affaiblies dans une sous-classe. Cela signifie que vous ne pouvez pas avoir une sous-classe avec des postconditions plus faibles que celles de sa superclasse.

 

Ségrégation des interfaces (Interface segregation principle)

Préférer plusieurs interfaces spécifiques pour chaque client plutôt qu'une seule interface générale.

Le principe de ségrégation des interfaces est une bonne pratique de la programmation orientée objet, qui stipule qu'aucun client ne devrait dépendre de méthodes qu'il n'utilise pas1.

Il faut donc diviser les interfaces volumineuses en plus petites plus spécifiques, de sorte que les clients n'ont accès qu'aux méthodes intéressantes pour eux.

Ces interfaces rétrécies sont également appelées interfaces de rôle.

Tout ceci est destiné à maintenir un système à couplage faible, donc plus facile à refactoriser (à modifier).

 

Inversion des dépendances (Dependency inversion principle)

Il faut dépendre des abstractions, pas des implémentations!

En suivant ce principe, la relation de dépendance conventionnelle que les modules de haut niveau ont, par rapport aux modules de bas niveau, est inversée dans le but de rendre les premiers indépendants des seconds.

Les deux assertions de ce principe sont :

  • Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau. Les deux doivent dépendre d'abstractions.
  • Les abstractions ne doivent pas dépendre des détails. Les détails doivent dépendre des abstractions.