Les principes solides sont-ils vraiment solides?
Le modèle de conception la première lettre de cet acronyme représente le principe de Responsabilité Unique. Voici une citation:
Le principe de la responsabilité unique stipule que chaque objet doit avoir un responsabilité unique, et que la responsabilité devrait être entièrement encapsulé par la classe.
C'est simple et clair jusqu'à ce que nous commencions à coder. Supposons que nous avons une classe avec une responsabilité unique. Pour sérialiser les instances de classe dont nous avons besoin pour ajouter des atrributs à cette classe. Alors maintenant, la classe a une autre responsabilité. Cela ne viole-t-il pas le SRP?
Voyons un autre exemple - une implémentation d'interface. Lorsque nous implémentons une interface, nous ajoutons simplement d'autres responsabilités, disons l'élimination de ses ressources ou la comparaison de ses instances ou autre.
Donc ma question. Est - il possible de garder strictement à SRP? Comment peut-il être fait?
10 réponses
Comme vous le découvrirez un jour, aucun des principes les plus connus dans le développement logiciel ne peut être suivi à 100%.
La programmation consiste souvent à faire des compromis - pureté abstraite vs Taille du code vs Vitesse VS efficacité.
Vous avez juste besoin d'apprendre à trouver le bon équilibre: ne laissez pas votre application tomber dans l'abîme du chaos mais ne vous attachez pas les mains avec une multitude de couches d'abstraction.
Je ne pense pas qu'être sérialisable ou jetable équivaut à de multiples responsabilités.
Eh bien, je suppose que la première chose à noter est que ce ne sont que de bons principes D'ingénierie logicielle-vous devez également appliquer le jugement. Donc, en ce sens-non, ils ne sont pas solides (!)
Je pense que la question soulève le point clé - comment définissez-vous la seule responsabilité exclusive, que la classe devrait avoir?
Il est important de ne pas trop s'enliser sur les détails lors de la définition d'une responsabilité-juste parce qu'une classe fait beaucoup de choses dans le code ne signifie pas qu'elle en a beaucoup responibilities.
Cependant, veuillez vous en tenir à cela. Bien qu'il soit probablement impossible d'appliquer dans tous les cas - c'est toujours mieux que d'avoir un seul "objet Dieu" (anti-Pattern) dans votre code.
Si vous rencontrez des problèmes avec ceux-ci, je vous recommande de lire ce qui suit:
Refactoring-Martin Fowler: bien qu'il s'agisse évidemment de refactoring, ce livre est également très utile pour montrer comment décomposer les problèmes en leurs parties logiques ou resposibilities-qui est la clé de SRP. Ce livre aborde également les autres principes-mais il le fait de manière beaucoup moins académique que vous avez peut-être vu auparavant.
Code propre-Robert Martin: qui de mieux à lire que le plus grand exposant des principes solides. Sérieusement, j'ai trouvé que c'était un livre vraiment utile dans tous les domaines de l'Artisanat logiciel-pas seulement les principes solides. Comme le livre de Fowler, ce livre est présenté à tous les niveaux d'expérience, donc je le ferais recommander à personne.
Pour mieux comprendre les principes solides, vous devez comprendre le problème qu'ils résolvent:
La programmation orientée objet est née de la programmation structurée / procédurale-elle a ajouté un nouveau système organisationnel (classes, et al.) ainsi que des comportements (polymorphisme, héritage, composition). Cela signifiait que OO n'était pas séparé de structuré/procédural, mais était une progression, et que les développeurs pouvaient faire Très procédural oo s'ils le voulaient.
Donc... Solide est venu autour comme quelque chose d'un test décisif pour répondre à la question de "Est-ce que je fais vraiment OO, ou est-ce que j'utilise juste des objets procéduraux?"Les 5 principes, s'ils sont suivis, signifie que vous êtes assez loin du côté OO du spectre. Ne pas respecter ces règles ne signifie pas que vous ne faites pas OO, mais cela signifie que c'est beaucoup plus structurel/procédural OO.
Il y a une préoccupation légitime ici, car ces préoccupations transversales (sérialisation, journalisation, notification de liaison de données, etc.) finissent par ajouter implémentation à plusieurs classes qui ne sont là que pour supporter un autre sous-système. Cette implémentation doit être testée, donc la classe a certainement été accablée de responsabilités supplémentaires.
La programmation orientée Aspect est une approche qui tente de résoudre ce problème. Un bon exemple en C# est la sérialisation, pour lesquelles il existe un large éventail d'attributs différents pour différents types de sérialisation. L'idée ici est que la classe ne devrait pas implémenter le code qui effectue la sérialisation, mais plutôt déclarer comment elle doit être sérialisée. Les métadonnées sont un endroit très naturel pour inclure des détails importants pour d'autres sous-systèmes, mais non pertinents pour l'implémentation testable d'une classe.
La chose à retenir sur les principes de conception est qu'il y a toujours des exceptions, et vous ne trouverez pas toujours que votre scénario/implémentation correspond à un principe donné à 100%.
Cela étant dit, ajouter des attributs aux propriétés n'ajoute pas vraiment de fonctionnalité ou de comportement à la classe, en supposant que votre code de sérialisation/désérialisation se trouve dans une autre classe. Vous ajoutez simplement des informations sur la structure de votre classe, donc cela ne semble pas être une violation de la principe.
Je pense qu'il y a beaucoup de tâches mineures et communes qu'une classe peut faire sans elles obscurcissant la responsabilité principale d'une classe: sérialisation, journalisation, gestion des exceptions, gestion des transactions, etc.
C'est à votre jugement de savoir quelles tâches dans votre classe constituent une responsabilité réelle en termes de logique métier / application, et ce qui est juste du code de plomberie.
Donc, si au lieu de concevoir une classe "Dog" avec des méthodes" Bark"," Sleep "et" Eat", je dois concevoir des classes" AnimalWhoBarks"," AnimalWhoSleeps"," AnimalWhoEats", etc? Pourquoi? Comment ce faire de mon mieux? Comment suis-je censé simplement mettre en œuvre le fait que mon chien n'ira pas dormir et aboiera toute la nuit s'il n'a pas mangé?
"diviser les grandes classes en plus petites", est un bon conseil pratique, mais "chaque objet devrait avoir une seule responsabilité" est un dogmatique absolu de la POO absurdité.
Imaginez que le framework. net a été écrit avec SRP à l'esprit. Au lieu de 40000 classes, vous auriez des millions.
SRP généralisée ("généralisée" est le mot important ici) est juste un crime à mon humble avis. Vous ne pouvez pas réduire le développement logiciel à 5 principes livresques.
En changeant votre définition de "responsabilité unique" - les principes solides sont assez liquides et (comme d'autres acronymes accrocheurs d'Acronymes) ne signifient pas ce qu'ils semblent vouloir dire.
Ils peuvent être utilisés comme une liste de contrôle ou une feuille de triche, mais pas comme des lignes directrices complètes et certainement pas du matériel d'apprentissage.
S. O. L. I. D signifie:
- Principe de responsabilité Unique
- Principe ouvert-fermé
- principe de substitution de Liskov
- principe de ségrégation de L'Interface
- Principe d'inversion de dépendance
Ce sont les normes auxquelles nous nous référons, quand nous parlons de POO. Cependant, aucun de ces principes ne peut être parfaitement respecté dans le développement de logiciels.
Vous pouvez voir une présentation très bien expliquante sur ce sujet ici http://www.slideshare.net/jonkruger/advanced-objectorientedsolid-principles