Si vous avez une classe qui hérite de deux classes distinctes, cela ne signifie-t-il pas que votre sous-classe fait automatiquement (au moins) 2 choses, une de chaque superclasse?
Je crois qu'il n'y a aucune différence si vous avez un héritage d'interfaces multiples.
Edit: Pour être clair, je crois que si le sous-classement de plusieurs classes viole SRP, alors la mise en œuvre de plusieurs interfaces (non marqueurs ou interface de base (par exemple comparable)) viole également SRP.
object-oriented
object-oriented-design
single-responsibility
multiple-inheritance
m3th0dman
la source
la source
Réponses:
Dans un sens très étroit, la réponse est "Oui": en supposant que vos classes ou interfaces de base sont conçues dans un seul but, l'héritage des deux crée une classe avec plusieurs responsabilités. Cependant, que ce soit ou non "une mauvaise chose" dépend de la nature des classes ou des interfaces dont vous héritez.
Vous pouvez partitionner vos classes et vos interfaces en deux groupes principaux - ceux qui traitent de la complexité essentielle de votre système et ceux qui traitent de sa complexité accidentelle. S'il hérite de plusieurs classes de "complexité essentielle", c'est mauvais; si vous héritez d'une classe "essentielle" et d'une ou plusieurs classes "accidentelles", c'est OK.
Par exemple, dans un système de facturation, vous pouvez avoir des classes pour représenter les factures et les cycles de facturation (elles traitent de la complexité essentielle) et des classes pour les objets persistants (elles traitent de la complexité accidentelle). Si vous héritez comme ça
c'est mauvais: votre
BillingCycleInvoice
responsabilité est mixte en ce qui concerne la complexité essentielle du système.D'un autre côté, si vous héritez comme ça
votre classe est OK: techniquement, elle dessert deux préoccupations à la fois, mais comme une seule d'entre elles est essentielle, vous pouvez radier l'héritage accidentel du "coût de faire des affaires".
la source
Le SRP est une directive pour éviter les classes divines, qui sont mauvaises, mais il peut également être pris trop à la lettre et un projet démarre avec des tonnes de classes qui ne peuvent vraiment rien faire sans qu'une poignée soit combinée. L'héritage multiple / les interfaces multiples peuvent être un signe qu'une classe devient trop grande, mais cela pourrait aussi être un signe que votre concentration est beaucoup trop granulaire pour la tâche à accomplir et que votre solution est sur-conçue, ou elle pourrait simplement être parfaitement cas d'utilisation valide pour l'héritage multiple et vos inquiétudes ne sont pas fondées.
La conception de logiciels est autant de l'art que de la science, c'est un équilibre entre de nombreux intérêts concurrents. Nous avons des règles pour éviter que les choses que nous savons vont trop loin dans une direction qui causent des problèmes, mais ces règles peuvent tout aussi bien nous emmener dans un endroit tout aussi mauvais ou pire que ce que nous essayions d'éviter en premier lieu.
la source
Quelque peu. Concentrons-nous sur le principe principal de SRP:
L'héritage multiple ne force pas cela, mais tend à y conduire. Si la classe remplace ou implémente ses classes de base, cela a tendance à être plus de raisons de changer. De cette façon, l'héritage multiple d'interface a tendance à être plus gênant que l'héritage de classe. Si deux classes sont héritées mais non remplacées, les raisons du changement existent dans les classes de base et non dans la nouvelle classe.
Les endroits où l'héritage multiple ne viole pas SRP est lorsque tous les types de base sauf un ne sont pas quelque chose que la classe implémente, mais agissent comme un trait que la classe a. Considérez
IDisposable
en C #. Les choses jetables n'ont pas deux responsabilités, l'interface agit simplement comme une vue dans les classes qui partagent le trait mais ont des responsabilités décidément différentes.la source
Pas à mon avis. Pour moi, une seule responsabilité est de "modéliser un utilisateur de mon application". Il se peut que je doive fournir ces données via un service Web et les stocker dans une base de données relationnelle. Je pourrais fournir cette fonctionnalité en héritant de deux classes mixtes.
Cela ne signifie pas que la classe a trois responsabilités. Cela signifie qu'une partie de la responsabilité de modéliser un utilisateur nécessite la prise en charge de la sérialisation et de la persistance.
la source
Pas du tout. En Java, vous pouvez avoir une interface qui représente une sorte d'objet de domaine - un Foo, par exemple. Il peut être nécessaire de le comparer à d'autres objets Foo, et il implémente donc Comparable (avec la logique de comparaison externalisée dans une classe Comparator); il se peut que cet objet doive également être sérialisable, afin qu'il puisse être transporté à travers le réseau; et il peut être nécessaire de le cloner. Ainsi, la classe implémente trois interfaces mais n'a aucune logique interne pour les prendre en charge au-delà de celle prise en charge par Foo.
Cela dit, il est stupide de pousser le SRP à l'extrême. Si une classe définit plus d'une méthode, viole-t-elle le SRP? Tous les objets Java ont une méthode toString () et une méthode equals (Object), ce qui signifie que CHAQUE objet en Java est responsable de l'égalité et de l'auto-représentation. Est-ce une mauvaise chose?
la source
Je suppose que cela dépend de la façon dont vous définissez la responsabilité. Dans l'exemple iostream classique, il ne viole pas le SRP. L'IOstream est responsable de la gestion d'un flux bidirectionnel.
Après avoir épuisé vos responsabilités primitives, vous passez à des responsabilités plus générales de haut niveau, après tout, comment définissez-vous la responsabilité de votre principal point d'entrée? Sa responsabilité doit être «être le principal point d'entrée» et non «tout ce que fait mon application», sinon il est impossible de ne pas violer le SRP et de produire une application.
la source