Les principes SOLID con­sis­tent en cinq pratiques et di­rec­tives pour un code propre, main­te­nable et flexible lors de la pro­gram­ma­tion orientée objet (OOP). L’ap­pli­ca­tion et le respect de ces principes per­met­tent de concevoir des logiciels faciles à com­prendre sur de longues périodes de dé­ve­lop­pe­ment. De cette manière, il est possible non seulement de produire un meilleur code, mais aussi de mieux en­tre­te­nir le code existant.

SOLID Prin­ciples : qu’est-ce que c’est ?

Au début d’un bon code source, il y a des règles, des pa­ra­digmes de pro­gram­ma­tion et un style de pro­gram­ma­tion approprié pour un code efficace et propre. C’est pré­ci­sé­ment ce que font les cinq principes SOLID (SOLID Prin­ciples, en anglais), forgés par Robert C. Martin, Bertrand Meyer et Barbara Liskov. En res­pec­tant certains principes dans la pro­gram­ma­tion orientée objet (OOP) avec des langages comme Python ou Java, on écrit non seulement un meilleur code, mais on assure aussi à long terme une main­te­nance plus efficace du code, une con­cep­tion durable et flexible du logiciel et une sécurité accrue.

Le terme SOLID désigne d’une part la base de dé­ve­lop­pe­ment solide pour tous ceux qui veulent apprendre à pro­gram­mer. D’autre part, l’abré­via­tion se compose des premières lettres de chacun des cinq principes :

  • Single Res­pon­si­bi­lity Principle ou Principe de Res­pon­sa­bi­lité Unique : une classe ne doit avoir qu’une seule res­pon­sa­bi­lité (et non une seule tâche) et une seule raison de changer.
  • Open Closed Principle ou Principe d’Ouverture/Fermeture : les classes doivent être ouvertes aux ex­ten­sions et fermées aux mo­di­fi­ca­tions.
  • Liskov Subs­ti­tu­tion Principle ou Principe de Subs­ti­tu­tion de Liskov : les sous-classes doivent pouvoir hériter et im­plé­men­ter toutes les méthodes et pro­prié­tés de la su­per­classe.
  • Interface Se­gre­ga­tion Principle ou Principe de Sé­gré­ga­tion des in­ter­faces : les in­ter­faces ne doivent pas contenir plus de méthodes qu’il n’en faut pour les classes qui les im­plé­men­tent.
  • De­pen­dency Inversion Principle ou Principe d’Inversion de Dé­pen­dance : les classes ne doivent pas dépendre d’autres classes, mais d’in­ter­faces ou de classes abs­traites.

SOLID Prin­ciples : les avantages

Là où il n’y a pas de règles, le chaos s’installe : cela devient évident lorsque l’on programme. Même de petites erreurs, im­pré­ci­sions et lacunes peuvent, si elles restent « non traitées », rendre à long terme un bon code source to­ta­le­ment inu­ti­li­sable. Il suffit de peu de choses : des classes complexes qui com­pli­quent l’im­plé­men­ta­tion ou encore des sous-classes aux­quelles il manque certaines pro­prié­tés de leurs su­per­classes. Le respect des principes SOLID permet qu’il y ait le moins possible de ré­pa­ra­tion de code par re­fac­to­ring.

Les avantages de l’ap­pli­ca­tion des SOLID Prin­ciples per­met­tent que le code soit :

  • Clair, propre et beau : les logiciels et les codes sont plus faciles à com­prendre, plus com­pré­hen­sibles, plus efficaces et tout sim­ple­ment plus beaux.
  • Facile à en­tre­te­nir : grâce à une structure claire et concise, il est plus facile d’en­tre­te­nir et de maintenir le code, qu’il soit nouveau ou qu’il ait évolué au fil du temps, même si plusieurs personnes sont im­pli­quées.
  • Adaptable, ex­ten­sible, réu­ti­li­sable : grâce à une meilleure li­si­bi­lité, à une réduction des com­plexi­tés et des res­pon­sa­bi­li­tés ainsi qu’à une réduction des dé­pen­dances entre les classes, le code peut être plus fa­ci­le­ment édité, adapté, étendu par des in­ter­faces et réutilisé de manière flexible.
  • Moins sujet aux erreurs : avec un code propre et une structure simple, les mo­di­fi­ca­tions apportées à une partie n’ont pas d’impact in­vo­lon­taire sur d’autres domaines ou fonctions.
  • Plus sûr et plus fiable : en réduisant ou en éliminant les points faibles, les in­com­pa­ti­bi­li­tés ou les erreurs, on améliore la fonc­tion­na­lité et la fiabilité des systèmes, et donc la sécurité.

SOLID Prin­ciples : les 5 principes en revue

Les principes SOLID comptent parmi les règles d’or d’une bonne pro­gram­ma­tion et devraient donc être familiers à tous ceux qui s’in­té­res­sent à la pro­gram­ma­tion orientée objet. Découvrez les 5 principes :

SRP : Single Res­pon­si­bi­lity Principle (Principe de Res­pon­sa­bi­lité Unique)

La dé­fi­ni­tion originale selon Robert C. Martin dans Agile Software De­ve­lop­ment: Prin­ciples, Patterns and Practices est la suivante :

Citation

« Il ne devrait jamais y avoir plus d’une raison de changer une classe. »

Le SRP stipule qu’une seule res­pon­sa­bi­lité doit s’appliquer à chaque classe dans l’OOP. Il ne doit donc y avoir qu’une seule raison pour modifier une classe. Con­trai­re­ment à de fréquents ma­len­ten­dus, cela ne signifie pas qu’une classe ou un module ne doit avoir qu’une seule res­pon­sa­bi­lité, mais qu’elle ne doit être res­pon­sable que de tâches spé­ci­fiques qui, si possible, ne se che­vauchent pas avec d’autres domaines.

Un che­vau­che­ment des res­pon­sa­bi­li­tés, par exemple en four­nis­sant des fonctions à dif­fé­rents domaines d’activité, peut avoir des ré­per­cus­sions sur la fonc­tion­na­lité de la classe en cas de mo­di­fi­ca­tion d’un domaine. En raison de plus d’une res­pon­sa­bi­lité et de trop de dé­pen­dances, une mo­di­fi­ca­tion dans un domaine peut entraîner plusieurs autres mo­di­fi­ca­tions ou des erreurs de code.

Le SRP a donc pour objectif de dé­ve­lop­per des modules cohérents, res­pon­sables d’une tâche clai­re­ment com­pré­hen­sible ou d’objets clai­re­ment définis. Grâce à une forme clai­re­ment struc­tu­rée avec des dé­pen­dances réduites et des im­plé­men­ta­tions dé­cou­plées, les mo­di­fi­ca­tions et mo­du­la­tions ul­té­rieures sont plus simples, plus rapides et sans com­pli­ca­tions.

Note

Les classes, également connues sous le nom de types d’objets ou modules, sont l’élément central de la pro­gram­ma­tion orientée objet (OOP). Elles peuvent être con­si­dé­rées comme des modèles de cons­truc­tion avec des attributs pour créer des objets logiciels réels, si­mi­laires à ceux cons­truits dans le monde réel. Les classes sont donc souvent comparées à des plans ou des modèles pour créer des objets, plutôt qu’à des types de fichiers.

OCP : Open Closed Principle (Principe d’Ouverture et de Fermeture)

Selon Bertrand Meyer et Robert C. Martin dans Object Oriented Software Cons­truc­tion, la dé­fi­ni­tion de l’OCP est la suivante :

Citation

« Les entités lo­gi­cielles (classes, modules, fonctions, etc.) devraient être à la fois ouvertes aux ex­ten­sions et fermées aux mo­di­fi­ca­tions. »

L’OCP veille à ce que vous n’ayez pas à réécrire le cœur d’un logiciel pour mettre en œuvre des mo­di­fi­ca­tions. Si des mo­du­la­tions profondes du code sont né­ces­saires, des risques d’erreurs subtiles et de code smell ap­pa­rais­sent. Un code bien structuré devrait pouvoir être doté d’in­ter­faces per­met­tant d’ajouter des fonctions sup­plé­men­taires. Le mot-clé ici est héritage de classe.

Les nouvelles fonc­tion­na­li­tés et ex­ten­sions peuvent être fa­ci­le­ment rat­ta­chées à une su­per­classe sous forme de sous-classes via une interface. De cette manière, il n’est pas né­ces­saire de « bi­douil­ler » le code déjà écrit et stable. Cela facilite la main­te­nance et l’entretien des pro­grammes et rend la réu­ti­li­sa­tion d’éléments de code stables beaucoup plus efficace grâce aux in­ter­faces.

LSP : Liskov Subs­ti­tu­tion Principle (Principe de Subs­ti­tu­tion de Liskov)

Selon Barbara H. Liskov et Jeannette M. Wing dans Be­ha­vio­ral Subtyping Using In­va­riants and Cons­traints, voici le concept du LSP :

Citation

« Soit q (x) une propriété de l’objet x de type T, alors q (y) devrait s’appliquer à tous les objets de type S, où S est un sous-type de T ».

Ce qui semble énig­ma­tique au premier abord est en fait facile à com­prendre : les sous-classes liées ou étendues doivent fonc­tion­ner comme leurs su­per­classes ou classes de base. Cela signifie que chaque sous-classe doit recevoir les pro­prié­tés de sa su­per­classe par le biais de l’héritage. Ces pro­prié­tés ne doivent pas subir de mo­di­fi­ca­tions dans la sous-classe. Elles doivent être rem­pla­çables par principe ; d’où le principe de subs­ti­tu­tion. Les su­per­classes, en revanche, peuvent être modifiées.

L’exemple du rectangle et du carré de Robert C. Martin sert d’il­lus­tra­tion. En géométrie, tout carré est un rectangle, en revanche, la ré­ci­proque n’est pas vraie : un rectangle n’est pas un carré. Un carré partage la propriété « côtés per­pen­di­cu­laires » avec la classe su­pé­rieure des rec­tangles, mais présente la propriété sup­plé­men­taire « côtés de même longueur ».

Il en va autrement en pro­gram­ma­tion : l’hypothèse selon laquelle des classes si­mi­laires ou ap­pa­rem­ment iden­tiques se réfèrent les unes aux autres ou dépendent les unes des autres conduit à des erreurs, des ma­len­ten­dus et un code peu clair. C’est pourquoi, en pro­gram­ma­tion, la classe « rectangle » n’est pas un carré et la classe « carré » n’est pas un rectangle. Les deux sont « découplés » et im­plé­men­tés sé­pa­ré­ment. Sans lien intégré entre les classes, un ma­len­tendu ne peut pas conduire à des erreurs in­ter­classes. Cela augmente la sécurité et la stabilité lors de l’échange d’im­plé­men­ta­tions dans des sous-classes ou des su­per­classes sans avoir d’impact.

ISP : Interface Se­gre­ga­tion Principle (Principe de Sé­pa­ra­tion des In­ter­faces)

L’ISP se définit selon Robert C. Martin dans The Interface Se­gre­ga­tion Principle de la manière suivante :

Citation

« Les clients ne devraient pas être con­traints de dépendre d’in­ter­faces qu’ils n’utilisent pas. »

L’ISP stipule que les uti­li­sa­teurs ne devraient pas être con­traints d’utiliser des in­ter­faces dont ils n’ont pas besoin. En d’autres termes, pour mettre à la dis­po­si­tion des clients les fonctions de certaines classes, de nouvelles in­ter­faces plus petites sont conçues pour répondre à des besoins concrets. Cela permet d’éviter que les in­ter­faces ne de­vien­nent trop grandes et que de fortes dé­pen­dances ne se créent entre les classes. L’avantage : un logiciel avec des classes dé­cou­plées et plusieurs petites in­ter­faces adaptées à des exigences concrètes est plus facile à en­tre­te­nir.

DIP : De­pen­dency Inversion Principle (Principe d’Inversion des Dé­pen­dances)

Selon Robert C. Martin dans The De­pen­dency Inversion Principle, le cinquième et dernier des principes SOLID s’énonce comme suit :

Citation

« A. Les modules de haut niveau ne devraient pas dépendre des modules de bas niveau. Les deux devraient dépendre d’abs­trac­tions. B. Les abs­trac­tions ne devraient pas dépendre des détails. Les détails devraient dépendre des abs­trac­tions. »

Le DIP veille à ce que les fonctions et dé­pen­dances concrètes dans les niveaux de code source reposent sur des in­ter­faces abs­traites et non les unes sur les autres. En clair : les ar­chi­tec­tures lo­gi­cielles peuvent être gros­siè­re­ment divisées en niveaux d’uti­li­sa­teurs su­pé­rieurs et en niveaux abstraits in­fé­rieurs ou plus profonds. D’un point de vue purement logique, on peut supposer que la base abstraite détermine le com­por­te­ment des niveaux su­pé­rieurs. Le DIP y voit toutefois un risque d’erreur, car il en résulte une dé­pen­dance des niveaux su­pé­rieurs vis-à-vis des niveaux in­fé­rieurs.

Au lieu de coupler les niveaux su­pé­rieurs aux niveaux in­fé­rieurs, les classes des niveaux su­pé­rieurs et in­fé­rieurs devraient dépendre d’in­ter­faces abs­traites in­ter­mé­diaires. Les in­ter­faces ré­cu­pè­rent les fonc­tion­na­li­tés né­ces­saires aux niveaux su­pé­rieurs et les mettent à dis­po­si­tion des niveaux in­fé­rieurs. Cela permet d’éviter une hié­rar­chie « bottom-to-top » (du bas vers le haut) de dé­pen­dances qui, avec le temps, peut entraîner des erreurs dans le code. Cela facilite la réu­ti­li­sa­tion des modules et permet d’apporter des mo­di­fi­ca­tions aux classes in­fé­rieures sans affecter les niveaux su­pé­rieurs.

Hé­ber­ge­ment Web
Hé­ber­ge­ment Web de pointe au meilleur prix
  • 3x plus rapide, 60 % d'éco­no­mie
  • Haute dis­po­ni­bi­lité >99,99 %
  • Seulement chez IONOS : jusqu'à 500 Go inclus

Que se passe-t-il en cas de non-respect des SOLID Prin­ciples ?

Un code beau et facile à lire, qui facilite autant que possible la main­te­nance, devrait être l’objectif de tout dé­ve­lop­pe­ment de logiciel. Mais si des di­rec­tives comme les principes SOLID sont oubliées, le code vieillit très mal en raison de points faibles, de re­don­dances, d’erreurs ac­cu­mu­lées et de trop nom­breuses dé­pen­dances. Dans le pire des cas, le code devient inu­ti­li­sable avec le temps. Cela constitue un problème majeur, notamment dans le dé­ve­lop­pe­ment agile de logiciels, où de nom­breuses personnes tra­vail­lent gé­né­ra­le­ment sur un code complexe.

Parmi les con­sé­quences d’un code malpropre ou d’une mauvaise main­te­nance du code, on peut citer :

  • Code smell : les points faibles his­to­riques dus à un code malpropre, connus sous le nom de code smell ou « code qui sent mauvais », en­traî­nent des erreurs de fonc­tion­ne­ment et des pro­grammes in­com­pa­tibles.
  • Code rouge : s’il n’est pas entretenu ou réparé par re­fac­to­ring ou par un code review coûteux, le code peut « pourrir » et perdre com­plè­te­ment sa fonc­tion­na­lité. Un autre terme pour un code illisible et confus est le code spaghetti.
  • Les failles de sécurité : un code malpropre peut avoir pour con­sé­quence des pannes, une main­te­nance com­pli­quée ou des in­com­pa­ti­bi­li­tés, mais aussi des failles de sécurité qui offrent aux logiciels mal­veil­lants la pos­si­bi­lité de créer des exploits ainsi que des attaques zero-day.

SOLID Prin­ciples : d’où viennent-ils ?

L’origine des SOLID Prin­ciples réside dans plusieurs principes in­tro­duits pour la première fois par Robert C. Martin (« Uncle Bob »), l’un des ini­tia­teurs de la pro­gram­ma­tion agile, dans son essai « Design Prin­ciples and Design Patterns » en 2000. Le groupe d’où sont issus les cinq principes SOLID a été cofondé par Robert C. Martin, Bertrand Meyer et Barbara Liskov. L’acronyme, facile à retenir et composé des cinq premières lettres des principes, a été répandu par Michael Feathers.

Y a-t-il d’autres principes de pro­gram­ma­tion si­mi­laires ?

Dans le dé­ve­lop­pe­ment de logiciels, les principes re­pré­sen­tent des lignes di­rec­trices et des re­com­man­da­tions d’action générales ou très concrètes, à l’instar des principes SOLID, qui offrent un ensemble de principes pour le paradigme de la pro­gram­ma­tion orientée objet. D’autres principes de pro­gram­ma­tion pour Clean Code sont par exemple :

  • Le principe DRY (Don’t repeat yourself), « ne vous répétez pas », pour les fonctions à re­pré­sen­ta­tion unique et univoque.
  • Le principe KISS (Keep it simple, stupid), « sim­pli­fiez, idiot », pour un code aussi simple que possible.
Aller au menu principal