In the SRP, a 'responsibility' is usually described as 'a reason to change', so that each class (or object?) should have only one reason someone should have to go in there and change it.
But if you take this to the extreme fine-grain you could say that an object adding two numbers together is a responsibility and a possible reason to change. Therefore the object should contain no other logic, because it would produce another reason for change.
I'm curious if there is anyone out there that has any strategies for 'scoping', the single-responsibility principle that's slightly less objective?
As the name suggests, this principle states that each class should have one responsibility, one single purpose. This means that a class will do only one job, which leads us to conclude it should have only one reason to change. We don't want objects that know too much and have unrelated behavior.
A class should have only one reason to change. This principle states that if we have 2 reasons to change for a class, we have to split the functionality in two classes. Each class will handle only one responsibility and if in the future we need to make one change we are going to make it in the class which handles it.
The argument for the single responsibility principle is relatively simple: it makes your software easier to implement and prevents unexpected side-effects of future changes.
Benefits of Single Responsibility Principle When an application has multiple classes, each of them following this principle, then the applicable becomes more maintainable, easier to understand. The code quality of the application is better, thereby having fewer defects.
it comes down to the context of what you are modeling. I've done some extensive writing and presenting on the SOLID principles and I specifically address your question in my discussions of Single Responsibility.
The following first appeared in the Jan/Feb 2010 issue of Code Magazine, and is available online at "S.O.L.I.D. Software Development, One Step at a Time"
The Single Responsibility Principle says that a class should have one, and only one, reason to change.
This may seem counter-intuitive at first. Wouldn’t it be easier to say that a class should only have one reason to exist? Actually, no-one reason to exist could very easily be taken to an extreme that would cause more harm than good. If you take it to that extreme and build classes that have one reason to exist, you may end up with only one method per class. This would cause a large sprawl of classes for even the most simple of processes, causing the system to be difficult to understand and difficult to change.
The reason that a class should have one reason to change, instead of one reason to exist, is the business context in which you are building the system. Even if two concepts are logically different, the business context in which they are needed may necessitate them becoming one and the same. The key point of deciding when a class should change is not based on a purely logical separation of concepts, but rather the business’s perception of the concept. When the business perception and context has changed, then you have a reason to change the class. To understand what responsibilities a single class should have, you need to first understand what concept should be encapsulated by that class and where you expect the implementation details of that concept to change.
Consider an engine in a car, for example. Do you care about the inner working of the engine? Do you care that you have a specific size of piston, camshaft, fuel injector, etc? Or, do you only care that the engine operates as expected when you get in the car? The answer, of course, depends entirely on the context in which you need to use the engine.
If you are a mechanic working in an auto shop, you probably care about the inner workings of the engine. You need to know the specific model, the various part sizes, and other specifications of the engine. If you don’t have this information available, you likely cannot service the engine appropriately. However, if you are an average everyday person that only needs transportation from point A to point B, you will likely not need that level of information. The notion of the individual pistons, spark plugs, pulleys, belts, etc., is almost meaningless to you. You only care that the car you are driving has an engine and that it performs correctly.
The engine example drives straight to the heart of the Single Responsibility Principle. The contexts of driving the car vs. servicing the engine provide two different notions of what should and should not be a single concept-a reason for change. In the context of servicing the engine, every individual part needs to be separate. You need to code them as single classes and ensure they are all up to their individual specifications. In the context of driving a car, though, the engine is a single concept that does not need to be broken down any further. You would likely have a single class called Engine, in this case. In either case, the context has determined what the appropriate separation of responsibilities is.
I tend to think in term of "velocity of change" of the business requirements rather than "reason to change" .
The question is indeed how likely stuffs will change together, not whether they could change or not.
The difference is subtle, but helps me. Let's consider the example on wikipedia about the reporting engine:
if the likelihood that the content and the template of the report change at the same time is high, it can be one component because they are apparently related. (It can also be two)
but if the likelihood that the content change without the template is important, then it must be two components, because they are not related. (Would be dangerous to have one)
But I know that's a personal interpretation of the SRP.
Also, a second technique that I like is: "Describe your class in one sentence". It usually helps me to identify if there is a clear responsibility or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With