Programmation de principes SOLID

43

Avec le temps, j'ai pu comprendre deux parties de SOLID : le «S» et le «O».

“O” - J'ai appris le principe de fermeture ouvert à l'aide de l'héritage et du modèle de stratégie.

"S" - J'ai appris le principe de responsabilité unique lors de l'apprentissage de l'ORM (la logique de persistance est retirée des objets du domaine).

De la même manière, quelles sont les meilleures régions / tâches pour apprendre d'autres parties de SOLID (le «L», le «I» et le «D»)?

Les références

  1. msdn - Dangers de la violation des principes SOLID en C #
  2. channel9 - Application des principes SOLID en .NET / C #
  3. Principes OOPS (Principes SOLID)
LCJ
la source
25
prenez note que toutes ces idées sont de bonnes idées et qu’elles sont très bonnes ensemble. mais si vous les appliquez dogmatiquement, ils provoqueront plus d'échecs que de succès.
3
Les OR-Mappers sont bons pour la séparation des problèmes, pas pour le principe de responsabilité unique. Consultez ce message programmers.stackexchange.com/questions/155628/… pour en savoir plus sur les différences.
Doc Brown
Exemples concrets blog.gauffin.org/2012/05/…
LCJ
1
@JarrodRoberson Yep, c'est pourquoi ils sont soigneusement appelés directives . N'oubliez pas non plus le reste des principes: adamjamesnaylor.com/2012/11/12/… (11 au total)
Adam Naylor
2
Le lien de @AdamNaylor est maintenant 404s, il a été déplacé vers adamjamesnaylor.com/post/…
mattumotu

Réponses:

54

J'étais à votre place il y a quelques mois jusqu'à ce que je trouve un article très utile.

Chaque principe est expliqué avec des situations réelles auxquelles chaque développeur de logiciel peut être confronté dans ses projets. Je suis en train de couper court et de montrer la référence: le développement de logiciels SOLID, une étape à la fois .

Comme indiqué dans les commentaires, il existe une autre très bonne lecture de pdf - SOLID Software Development de Pablo .

En outre, il existe de bons livres décrivant les principes SOLID de manière plus détaillée - Good Book on SOLID Software Development .

Éditer et commenter un bref résumé pour chaque principe:

  • «S» - Le principe de responsabilité unique est fondé sur les besoins de l’entreprise pour permettre le changement. «Une seule raison de changer» vous aide à comprendre quels concepts logiquement distincts doivent être regroupés en prenant en compte le concept et le contexte de l'entreprise, au lieu du seul concept technique. In another words, j’ai appris que chaque classe devrait avoir une responsabilité unique. La responsabilité est simplement d'accomplir la tâche assignée

  • "O" - J'ai appris le principe Open Closed et commencé à "préférer la composition à l'héritage", préférant ainsi les classes qui n'ont pas de méthodes virtuelles et qui sont éventuellement scellées, mais qui dépendent des abstractions pour leur extension.

  • “L” - J'ai appris le principe de substitution de Liskov à l'aide du modèle de référentiel permettant de gérer l'accès aux données.

  • “I” - J'ai appris le principe de séparation des interfaces en apprenant que les clients ne devraient pas être obligés d'implémenter des interfaces qu'ils n'utilisent pas (comme dans Membership Provider dans ASP.NET 2.0). Donc, l'interface ne devrait pas avoir «beaucoup de responsabilités»
  • “D” - J'ai découvert le principe d'inversion de dépendance et commencé à coder facilement . Plus facile à changer signifie un coût total de possession plus bas et une facilité d'entretien accrue.

Comme une ressource utile de CodePlex a été mentionnée dans les commentaires, référence est incluse à SOLID par exemple

entrez la description de l'image ici

EL Yusubov
la source
3
J'ai trouvé le recueil d'articles suivant très utile: lostechies.com/wp-content/uploads/2011/03/…
Scroog1
J'ai lu tout cet article et je ne suis pas vendu sur des modèles ni sur SOLID. L'exemple est trop simpliste, mais quand il devient complexe, cette complexité est artificielle. Je ne suis pas encore confronté au monde réel SOLO OOP sans meilleures alternatives.
Job
3
depuis que les articles de lostechies ont été mentionnés ici, il y a aussi ce solidexamples.codeplex.com (basé sur lostechies)
dark fader
2
J'étais l'un des contributeurs de Pablos eBook. Je suis content que les gens le trouvent toujours utile. :)
Sean Chambers
1
+1000000 si je pouvais pour votre résumé du principe Open-Closed - tout le monde se trompe et pense que c'est à propos de l'héritage
AlexFoxGill
11

(I) Séparation de l'interface et (D) ependency L'inversion peut être apprise via des tests unitaires et des moqueries. Si les classes créent leurs propres dépendances, vous ne pouvez pas créer de bons tests unitaires. S'ils dépendent d'une interface trop large (ou d'aucune interface du tout), vous ne saurez pas exactement à quoi se moquer pour effectuer vos tests unitaires.

StriplingWarrior
la source
2
+1 c'est très vrai. Vous n'avez même pas à adhérer à la règle (imo) parfois trop stricte «un test unitaire ne devrait tester qu'une chose»: si vous ne pouvez pas créer une suite de tests décente pour un cours en quelques minutes, viole I et D et probablement aussi le reste de l'alfabet
lundi
8

Le principe de substitution de Liskov ne vous permet fondamentalement pas de abuser de l'héritage d'implémentation: vous ne devez jamais utiliser l'héritage simplement pour la réutilisation de code (il existe une composition pour cela)! En adhérant au LSP, vous pouvez être à peu près sûr qu'il existe réellement une "relation de type" entre votre super-classe et votre sous-classe.

Cela dit, vos sous-classes doivent implémenter toutes les méthodes de la sous-classe de la même manière que l'implémentation des méthodes de la sous-classe. Vous ne devriez jamais écraser une méthode en implémentant NOP ou renvoyer null lorsque le sur-type lève une exception; comme indiqué dans les conditions de conception par contrat, vous devez respecter le contrat de la méthode de la superclasse lorsque vous passez outre une méthode. Un moyen de se défendre contre la violation de ce principe consiste à ne jamais ignorer une méthode mise en œuvre; au lieu de cela, extraire une interface et implémenter cette interface dans les deux classes.

Le principe de ségrégation d'interface , le principe de responsabilité unique et le principe de haute cohésion de GRASP sont en quelque sorte liés; ils se réfèrent au fait qu'une entité ne devrait être responsable que d'une seule chose, de sorte qu'il n'y ait qu'une seule raison de changer pour que le changement se fasse très facilement.

En fait, si une classe implémente une interface, elle doit implémenter et utiliser toutes les méthodes de cette interface. S'il existe des méthodes qui ne sont pas nécessaires dans cette classe particulière, l'interface n'est pas bonne et doit être scindée en deux interfaces, l'une ne contenant que les méthodes requises par la classe d'origine. On peut considérer qu’il s’agit d’un point de vue lié au principe précédent par le fait qu’il ne vous permet pas de créer de grandes interfaces, de sorte que leur implémentation risque de rompre le LSP.

Vous pouvez voir l' inversion de dépendance dans le modèle d'usine; Ici, le composant de haut niveau (le client) et le composant de bas niveau (instance individuelle à créer) dépendent de l'abstraction.(L'interface). Une façon de l'appliquer dans une architecture en couches: vous ne devez pas définir d'interface avec une couche de la couche implémentée, mais du module appelé. Par exemple, l'API de la couche source de données ne doit pas être écrite dans la couche source de données mais dans la couche logique d'entreprise, où il est nécessaire de l'appeler. De cette manière, la couche source de données hérite / dépend du comportement défini dans la logique de l'entreprise (donc de l'inversion) et non l'inverse (comme ce serait le cas de manière normale). Cela offre une flexibilité dans la conception, permettant à la logique métier de fonctionner sans changement de code, avec une autre source de données totalement différente.

m3th0dman
la source
1
Grande explication sur Liskov. :)
John Korsnes