Single Responsibility and Mixins

2019-04-27 14:45发布

问题:

Given that Mixins generally introduce new behaviour into a class, this generally implies that a class would have more than one behaviour.

If a class has a single responsibility this is defined as the class having only one reason for change.

So, I can see this from two different perspectives

  1. The class only has one reason for change. The module mixed in also has only one reason for change. If the class is changed only the class will need retesting. If the module is changed only the module needs retesting. Hence, SRP is intact.

  2. The class now has two reasons for change. If the class is changed, both class and module need retesting. If the module is changed, again both class and module need retesting. Henge, SRP is violated.

Does the use of mixins violate the Single Responsibility Principle, and ultimately result in a harder to maintain system?

回答1:

When you need to share behaviour among unrelated classes (and sometime you need to), there are essentially three options:

  1. Copy and paste everywhere. This violates DRY, is guaranteed to hurt maintainability.
  2. Put it into an abstract class and let all your classes (many of which are unrelated to each other) inherit from it. This is commonly considered an OO antipattern. Simply put, it totally knocks the concept of inheritance on the head. Just because foo and bar do some things the same, you don't claim that foo is-a bar.
  3. Put it somewhere else, give it a clear name, and mix it into all classes that need it.

As for testing, I would argue that a "good" mixin, just like a good regular method, should be coupled loosely enough that it and the classes using it can be used independently.



回答2:

I think it depends on the mixin. It might well give it additional responsibilities, but there are those like Ruby's Comparable which give pretty low-level functionality which I would say doesn't violate SRP.



回答3:

Given that Mixins generally introduce new behaviour into a class, this generally implies that a class would have more than one behaviour.

If that was true, it would be equally true of single (implementation) inheritance. While noone likes 23-deep inheritance hierarchies any more, it still has it's place.

The reason inheritance doesn't break the SRP is that the class it is talking about is the class in the sense of a literal code file, not anything more abstract. That file generally doesn't need to change if you change a base class code file.

So the single reason to change it is preserved.



回答4:

I would agree with that. However, the SRP can (or should) be violated sometimes.