I've read several articles on SRP and cohesion, and they seem to contradict each other as far as low coupling is concerned.

Articles on cohesion argue that putting closely related responsibilities together in a class Highly_Cohesive_Class reduces coupling, while articles on SRP would argue that we'd reduce coupling by removing these closely related responsibilities from class Highly_Cohesive_Class into separate classes ( such that each class only has single responsibility/reason to change ).

Don't the two claims contradict each other? Namely,

BTW - I'm aware of the fact that class adhering to SRP principle is also considered highly cohesive class, but in this post the term highly cohesive refers to a class that has several closely related responsibilities.

  • 5
    High cohesion: Embedding closely related functionalities in a class, SRP: There should never be more than one reason for a class to change - Doesn't "closely related" imply that if they are going to change they are going to change for the same reason? How can they be closely related if not? – yannis Aug 26 '12 at 19:48
  • 1
    Yes they are not synonyms, but they are very closely related ;) "high cohesion" is not a silver bullet, what you are looking for in your design, any design, is balance. If your design satisfies both principles, you are on the right path... – yannis Aug 26 '12 at 20:10
  • 1
    Well, it depends really, how about you point us to the articles you've read so we can see exactly what the authors had in mind? – yannis Aug 26 '12 at 21:17
  • 1
    Highly cohesive classes usually reduce coupling, that's generally true (high cohesion often correlates with low coupling). SRP also can help reduce coupling, for more or less the same reasons as high cohesion, I'm not sure why or how the articles lead you to believe that SRP and high cohesion are somehow contradictory. If anything, I'd say that in a balanced design they are complementary, and in an unbalance one it doesn't matter, as you probably have bigger problems ;) – yannis Aug 26 '12 at 22:08
  • 2
    Hm, I think the source of the confusion is the use of the word responsibility. Generally speaking high cohesion aims in grouping together related functionality that contributes to a single well defined task. What SRP adds to the picture is a logical constraint: Your task is truly a single one, when there's only one reason for it to change. If what you define as "related responsibility" is in fact different (functional / logical) tasks, then your class is not a highly cohesive one, but a mess ;) There is such a thing as too much cohesion. – yannis Aug 27 '12 at 1:29

I think the confusion is that high cohesion does not necessarily mean you want to put all of the "closely related responsibilities" in one class, but rather that all of the items in a class should correspond to closely related responsibilities.

For example, if you have a Kitchen class, you wouldn't want bathroom logic in it; however, you don't HAVE to also have oven and kitchen sink logic in it too, just because they are related. Although it is a kitchen appliance, the Oven probably deserves its own class, and would end up relating to the Kitchen through composition. Likewise the KitchenSink would be related to the Kitchen through composition.

So, look at a highly cohesive as NOT HAVING unrelated logic in it, and look a SRP as the call to delegate responsibilities to objects that serve that one responsibility.

  • hi, I understand the point you are making, but there may still be cases where we decide that highly cohesive class may have several responsibilities instead of just one. Now will in such cases this class usually be more or less coupled than if we break it into several SRP classes, and why? – user1483278 Aug 26 '12 at 23:33
  • 1
    @user1483278 You need to give us an example of what exactly you mean by "highly cohesive class may have several responsibilities instead of just one" (preferably by editing your question). Responsibility is such a wonderfully vague word, and quite possibly the source of the confusion in your question. – yannis Aug 27 '12 at 1:53
  • hi, I don't have any specific examples, since thus far my study of patterns is purely theoretical – user1483278 Aug 27 '12 at 21:00
  • Neither a kitchen nor a bathroom should "be" a sink, but it would seem better for a kitchen and a bathroom to implement a LiquidDisposer interface than to require clients to search the room for an object capable of disposing of liquid [e.g. a sink]. Even if all the actual functionality of a kitchen is handled in other classes, just the bindings between the interfaces a kitchen should support and the encapsulated objects that implement them would be fairly substantial. – supercat Dec 23 '13 at 22:01

You are mixing up the two. Responsibility is about behavior, about what a class should do or be capable of. Cohesion is more about components, about grouping classes that operate within the same domain. So you could have a class to contain some related data and another class to retrieve that type of data from a store. The data members in the class would be cohesive because they have little meaning on their own, they have meaning together (may come from the same table). And the classes could be in the same assembly because they both deal with offering access to data, which would make them cohesive.

Having separate classes for containing data and for fetching/storing data would comply to SRP. At the same time putting them in the same assembly would recognize their cohesiveness. You want to separate them yet keep them close together because they need each other.

The components in a car are highly cohesive, they work together. Yet it is a good thing the steering mechanics are separated from the gear box so you can maintain the two separately and modifying one will not impact the other. At the same time you as a driver want access to both when you drive so it is nice they are integrated in the same vehicle.

Not the answer you're looking for? Browse other questions tagged or ask your own question.