Low Coupling: Single Responsibility Principle vs Cohesion

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.

15

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.

4

Uncle Bob states in his book that this might be one of the least understood principles. I’ve seen lots of evidence of that in my career.

From his clean code blog:
The Single Responsibility Principle

Another wording for the Single Responsibility Principle is:
Gather together the things that change for the same reasons. Separate those things that change for different reasons.
If you think about this you’ll realize that this is just another way to define cohesion and coupling. We want to increase the cohesion between things that change for the same reasons, and we want to decrease the coupling between those things that change for different reasons.

However, as you think about this principle, remember that the reasons for change are people. It is people who request changes.

he also defines it as:

A module should be responsible to one, and only one, actor.

Yet another way to say this is that an SRP compatible component is one that when it does change it always changes with respect to its ability to fulfill a role for a specific audience. As a unit these functions satisfy a single need. Depending upon the language you use ‘component’ could mean a single package, class or file.

for example: consider a class that implements stove (from the post above) would have inputs (electricity/natural gas/propane) and outputs (BTUs and burner configurations and other features like self cleaning).

All of this stuff is related to the single job of cooking food and the cook is the single party that cares about combining these functions to achieve their goals. The SRP indicates that it is preferable to put all of these features in a single component. Some may be exposed and others completely internal.

The point is that there is very little reason to split these aspects away from the stove as they relate to the stove and to nothing else. Any cook can control these aspects through the stoves interface, the knobs and burners. Every cook wanting to use the stove will have exactly the same concerns and benefit from the interface in the same way. Because these functions are all inseparable from the stove (it isn’t as useful without them and they don’t apply to anything else) it is wise to collate them within it because they have high cohesion.

A frying pan on the other hand is a much smaller component that can be used with the stove but is not an integral part of it. When you replace the stove you don’t necessarily have to replace the frying pan.

The pan may have a simple interface like:
fry ( foodItem ); stop();

FoodItems might only have:
isDone();

So some components can be large and others small and where the line is drawn depends upon the component’s usage which is why I think there is so much confusion about the principle.

In an oversimplified but more pertinent coding-related example the one ‘person’ may be a developer that wants to access files or something like that. Here the single purpose is file I/O and the ‘audience’ is developers. They probably expect a useful file class to have several related functions on it like:

a = file.read()
file.seek(c)
file.write(b)
file.close()

These functions have high cohesion because they are intimately related to each other with respect to the file object the class represents. They make the file object highly useful and internal aspects of the file that the outside world need not be concerned with are encapsulated.

one could separate them into separate classes and pass a file object (or worse, the file name) into them. i.e. something like:

a = fileReader(file);
pos = fileSeeker(file, c);
fileWriter(file, b, pos);
fileCloser(file);

These objects “do one thing” but because they all operate on a file object and they are independent of other purposes splitting them up clutters the namespace for no gain. Note also that by turning the object ‘inside out’ the file position (pos) must now become an additional concern for the outside environment.

This supposed ‘application’ of the principle would really in fact be a ‘violation’ of it. There are many well-meaning but incorrect examples out there that would lead developers to the wrong conclusion. I think this is why Uncle Bob says it is one of the poorest understood of the SOLID principles.

It isn’t very cohesive to break up a component that performs interrelated operations on the same object(s). It should only be done if there are multiple classes of ‘consumers’ that depend upon the the same feature set but to achieve different ends.

1

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.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật