2

This question already has an answer here:

From Wikipedia on Single responsibility principle SoC

... class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility

class or module should have one, and only one, responsibility . As an example, consider a module that compiles and prints a report. Imagine such a module can be changed for two reasons. First, the content of the report could change. Second, the format of the report could change. These two things change for very different causes; one substantive, and one cosmetic. The single responsibility principle says that these two aspects of the problem are really two separate responsibilities, and should therefore be in separate classes or modules. It would be a bad design to couple two things that change for different reasons at different times.

The reason it is important to keep a class focused on a single concern is that it makes the class more robust. Continuing with the foregoing example, if there is a change to the report compilation process, there is greater danger that the printing code will break if it is part of the same class.

Is there a rule or general guideline on how to define responsibility of methods in class?

When we talk about objects inanimate objects its easy to see compile report and print report is two different responsibilities. However when it comes to animate objects like dog it becomes not so evident what methods are different in nature.

Say you have:

class dog {
   public $breed;
   public $age;
   public $color;

   function bark($loudness) (
      ...
   ) 

   function pee($amount) (
      ...
   ) 

   function run($speed, $distance, $direction) (
      ...
   ) 

   function growl() (
      ...
   ) 

   function drink() (
      ...
   ) 
} 

how can you tell what responsibility should be in a separate class?

marked as duplicate by gnat, Karl Bielefeldt, user22815, Greg Burghardt, Andres F. Nov 3 '16 at 18:27

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Your example methods all fit the dog nicely. Feed would not belong here, while Eat would (unless it is the dog itself that is eating and not being eaten). Choosing class names carefully is really important, it only gets hard and error prone if the name is ambiguous or does not map well to the world you want to model. The criterion is to look for dependencies. Is the bark operation external to the dog? No, the dog can do that all by itself. What about the feeding? It needs someone to feed it so feeding is not a dog operation. – Martin Maat Nov 3 '16 at 13:12
3

General

Single Responsibility has something to say about semantic redundancy and false semantic cohesion of code fragments (modules, classes, methods functions). The problem is (with all SOLID principles) it's not about applying them, it's about identifying a violation them. Once you think it violates SRP you can make a thought experiment (coordinated with your business people) your code has to pass to verify your assumption.

Semantic redundancy

If a functional requirement occurs and you have to change two code fragments for the same reason you violate the SRP.

This often happens if a developer does not know that some logic already exists that will solve a probem for him and he develops it once again.

False semantic cohesion

If a functional requirement occurs and you produce an unintentional side effect in another code fragment you violate the SRP.

This happens if technically savvy developers try to reduce code duplication without consider semantics.

E.g. a local part check for an email address was implemented at different locations of your code base. A developer extracts the code into one central method because it looks technically equal. Another time another developer has to change the local part check for one case and he does not check if all other usages will be correct under the new implementation.

Conclusion

Duplicate code may be a reason to think of SRP violation. But you have to be careful if you put code together that seems to be equal. You cannot escape from semantics. You have to identify what the code really means in the context to decide if there is a violation of SRP.

You can break it down to: You have to put things together that belong together and you have to isolate thing that do not belong together. But this is an identification process.

In your example you have a Dog class with several methods that represent actions of a dog. If you are paranoid you can see your first redundancies: All methods can be "executed". So "Execution" is what they all have in common. But we have a hard time to extract this part as the programming language itself takes care of the execution. So there are lower boundaries to SRP that are related to the used programming language.

Ok. Your dog barks, pees, drinks, growls and runs. I only can say, that I currently see no violation of SRP. But that doesn't mean there isn't. Once you find an indicator that may be semantically redundant or false in the context of semantic cohesion you can ignite.

After all I want to say that sometimes some SRP violation can be tolerated as the code is expected to be stable in changes. But this is only about to be pragmatic and never a rule.

11

The responsibility here is dog. Dog is as dog does.

Many people read the Single Responsibility Principle as "Must do only one thing." That's not what it means. Bob Martin, author of the principle (and prolific source of mass confusion for inexperienced programmers everywhere) says it like this:

Every class should have only one reason to change.

I view a class as embodying a "purpose" or "area of responsibility." If you write a class that contains Create, Read, Update and Delete methods, those aren't four responsibilities; they are just one: Data Access.

  • Change what? Code or State? Can't be state. Must be code. What's a reason? Must be a stakeholder, then. Whether the stakeholder is the Accounting department or me wearing my refactoring hat in service of "developers". If people don't understand what you mean, but it's really important, they better hire you to come train them in exactly what you do mean. – Aaron Hall Nov 2 '16 at 22:02
  • @AaronHall: Don't ask me. I'm not the one who coined the phrase. – Robert Harvey Nov 2 '16 at 22:04
  • 1
    More specifically, Dog should have only one reason to change: because it is doing Dog things: eating, sleeping, pooping, etc. Trying to shoehorn Cat things into Dog doesn't work. Dogs don't fit on sunny windowsills. But Dog can still do multiple things. – user22815 Nov 2 '16 at 23:00
  • 4
    +1 for prolific source of mass confusion for inexperienced programmers everywhere – jleach Nov 2 '16 at 23:40
  • 1
    @DavidArno: The answer is "No, there is no rule." If you dig into DDD or something similar, you might find organizational guidance that maps your classes to responsibilities in a sensible way that respects SRP. But SRP is littered with legitimate exceptions: IEquatable, ToString(), Reflection. It's hard to see how any of these could in any logical or common-sense way be viewed as part of a single responsibility. The best you can hope for is to get an intuitive sense from experience of "these two things do not naturally belong together." – Robert Harvey Nov 3 '16 at 2:23
1

I this conference in Yale, Uncle Bob gives this funny example:

enter image description here

He says that Employee has three reasons to change, three sources of change requirements, and gives this humorous, tongue-in-cheek, but illustrative nonetheless, explanation:

  • If the CalcPay() method has an error and costs the company millions of US$, the CFO will fire you.

  • If the ReportHours() method has an error and costs the company millions of US$, the COO will fire you.

  • If the WriteEmmployee() method has an error that causes the erasure of a lot of data and costs the company millions of US$, the CTO will fire you.

So having three different C level execs potentially firing you for costly errors in the the same class means the class has too many responsabilities.

He gives this solution that solves the violation of SRP but has yet to apply the DIP (Dependency Inversion Principle) which he explains but is not shown in the video because there's no camera shot to the slide while he does it.

enter image description here

  • What is DIP? ... – Robert Harvey Nov 3 '16 at 15:06
  • @RobertHarvey Dependency Inversion Principle. – Tulains Córdova Nov 3 '16 at 17:16
  • How would one "violate" the Dependency Inversion Principle? By not using it? – Robert Harvey Nov 3 '16 at 17:16
  • @RobertHarvey I changed "violates" to "he has yet to apply DIP". He actually does but in the video the camera was shooting him instead of the slide. – Tulains Córdova Nov 3 '16 at 17:21

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