Is high cohesion a synonym for the Single Responsibility Principle? If not, how are they different?
相关问题
- how to define constructor for Python's new Nam
- Keeping track of variable instances
- Object.create() bug?
- std::vector of objects / pointers / smart pointers
- Name for a method that has only side effects
相关文章
- 接口B继承接口A,但是又不添加新的方法。这样有什么意义吗?
- NameError: name 'self' is not defined, eve
- Implementation Strategies for Object Orientation
- Check if the Type of an Object is inherited from a
- When to use Interfaces in PHP
- Are default parameters bad practice in OOP?
- How to return new instance of subclass while initi
- In OOP, what is the best practice in regards to us
It's not a synonym. SRP (Single Responsibility Principle) is when you ensure yours classes will have only one responsibility. For sure this increases your classes cohesion.
But you can have high cohesion without following SRP to the letter.
Here is a good source on that.
You asked: If not, how are they different?
Single Responsibility Principle
Throw out whatever you think you guess this principle means.
Robert C. Martin officially defines this principle as:
Most people defining SRP are incorrect. SRP is typically mis-explained as:
"The
Employee
class shouldn'tUpdateDemographics()
andSendMessage()
, that counts as two responsibilities... putSendMessage()
into a Message class!!"^^ Wrong
vv Right
Robert C. Martin says
Robert C. Martin defines SRP as:
When a Stakeholder asks for a change to the data-sorting in the View, management shouldn't freak out and worry that the algorithms will break. Because The module that handles Sorting on the View is responsible only to the stakeholder, and The module that handles the total-calculating algorithm is responsible only to the business analyst. So when the Business Analyst asks to make a change to the algorithm, we shouldn't fear that the View will change.
Therefore, A module (singular) should only ever change for one reason: The Single Person-Role for whom this module serves has requested a change.
With that as your new foundation for the definition of SRP, you can now apply what you thought SRP was previously, and make the definition a bit more granular. Nobody is saying to put all of your front-end code into one module and all of your back-end code into one module.
High Cohesion
Imagine that you have a method
decimal CalculatePayFor(Employee)
and another methodvoid Pay(Employee)
Do these belong together? There could be a service that performs calculations of all sorts, and there could be a service that does nothing more than wrap the Human-Resources Payment SOAP. Perhaps
Pay(Employee)
calls intoCalculatePayFor(Employee)
, but just because they have the wordPay
in them doesn't mean they belong together!How do I create cohesion? - You don't. Cohesion is something you observe. What you do is Don't tear things apart that belong together.
It is possible to create a class for every public method you want. Each class now has one public method and everything is a well-defined mess. You have classes named
PayrollClass1
andPayrollClass2
because one does calculations one way, and the other does calculations two way.Some languages even benefit from a complete lack of classes, and methods run free. There is no grouping of methods, methods are just methods that you can call whenever. They're all pretty much static.
However, You Can Observe that
CalculatePayFor(Employee)
andPay(Employee)
are actually VERY Highly bound. They are like a dang married couple, and they look great together. When methods clearly belong together, you don't want to tear them apart. Observe their natural state and set up a wildlife preserve. This is Maintaining High Cohesion. You don't create it, you observe it.What this really helps with is Proper Code Duplication. For example,
PayrollService.CalculatePayFor(Employee)
has the same exact code asReportService.CalculatePayFor(Employee)
. Is this bad? Of course not. If Senior Management asks to make a change in the calculation for employee pay for the sake of reporting, that's a different responsibility than if H.R. tells you to make a change for the calculation for tax purposes for the actual payment method."Wait, did he just mix up SRP and Cohesion?" No, but I'm glad you recognized the mix-up. What if the ReportService reached into the PayrollService' class and used its method? Then when it changes for legitimate payment purposes, the reports all change... but management didn't want that!!! So since Cohesion forces methods to stay to their own classes, and SRP forces modules to keep to themselves within an application, the ReportService is forced to Copy/Paste the method from the PayrollService class. Now they can change independent of each other.
"But what if that isn't what you want?" Well, there are a lot of places in code where duplication is ruled out. But it is most common for algorithms to stick to themselves, and change independently of the dependencies. Even if that means duplication. It just depends what is needed. But Separation of Concerns, Single Responsibility, Cohesion, and DRY (Don't Repeat Yourself) are all separate ideas.
Side-Note: DRY Doesn't mean there is never duplication. As I mentioned: Many times you can have duplicate code because business rules are similar amongst different concerns, and have different reasons to change.
The are not the same thing.
You can have a highly cohesive class that does not have just a single responsibility.
In Robert Martin's own words,
See also: Difference between Single Responsibility Principle and Separation of Concerns.