The article critiques Uncle Bob's Single Responsibility Principle (SRP) definition, suggesting that defining reasons to change based on business functions is insufficient and proposes considering potential requirements as a better metric for module separation to improve code quality.
Abstract
The Single Responsibility Principle (SRP) is a key tenet of the SOLID principles in software design, advocating that each module should have a single reason to change. While Robert C. Martin ("Uncle Bob") defines this reason in terms of business functions, the author argues that this approach is difficult to apply and does not adequately address the complexities of real-world software development. The article posits that a more practical approach is to consider a reason to change as any potential requirement that could necessitate a module's alteration. This perspective aims to enhance code reusability, maintainability, and collaboration by ensuring that modules are granular enough to be independently modified without affecting unrelated parts of the system.
Opinions
Uncle Bob's SRP definition, which ties reasons for change to business functions, is seen as too abstract and hard to translate into practical development decisions.
The author believes that SRP should be applied by considering the likelihood of different requirements leading to changes in a module, rather than solely focusing on business function responsibilities.
The article suggests that separating modules by potential requirements, rather than business functions, is more effective in achieving the benefits of SRP, such as improved flexibility and team collaboration.
The author points out that even within the same business function, different requirements can necessitate the separation of concerns, which is not adequately addressed in Uncle Bob's SRP.
The author emphasizes that while the SRP is crucial for code quality, it is often not fully adhered to, especially in UI development, but adherence to the principle should be encouraged to the greatest extent possible.
SOLID: Single Responsibility Principle (SRP) — Why Uncle Bob’s Definition Is Not Good Enough
Introduction
The Single Responsibility Principle (SRP) is a fundamental concept in software design that got famous as the first part of the well-known SOLID principles defined by Robert C. Martin better known as “Uncle Bob”. His definition states that “each software module should have one and only one reason to change”. According to him, a reason for change is based on a business function that is represented by one person or a group of persons. While Uncle Bob is a legend with superior knowledge about all parts of programming, I want to argue that his definition of a reason to change in the SRP has some shortcomings that should be addressed to improve your code quality.
In the following, I give you a better understanding of the SRP in general by explaining the advantages of using the SRP, then describing the original version by Uncle Bob with its shortcomings and finally proposing an improved interpretation.
Why?
The Single Responsibility Principle (SRP) is a key aspect of the SOLID principles of software design. Key advantages are:
Better collaboration: By separating concerns into classes with a single responsibility, you make it easier to understand and update the code. This means that your current team or future developers will be able to understand the codebase faster and make changes without breaking other app parts.
Increased reusability: By encapsulating functionality in separate classes, you can reuse that code in other parts of your app or even in other apps. This reduces the amount of code duplication and can speed up development time.
Easier to change: By separating concerns into smaller classes, each with a single responsibility, you can modify or replace a single class without affecting the rest of the codebase. This can for example be useful when you want to switch from a local database to a remote database.
Easier testing: By isolating functionality in separate classes, you can test each class individually to make sure it works as expected. This reduces the complexity of testing and makes it easier to catch and fix bugs.
It is easy to understand that if a software module has more than one reason to change it should be separated into two or more modules. This can be realized by creating e.g. a new class or method.
Furthermore, it is necessary to define what a reason to change exactly is. Uncle Bob states that the principle is about people.
According to his blog post, it is crucial to ensure that changes made to a software module are initiated by a specific business function that could be represented by a single person or a group of people. The aim is to shield one specific module from the influence of multiple parts of the entire organization and develop systems in a way that every module serves the requirements of only that particular business function which helps to reduce complexity.
Shortcomings of Uncle Bob’s SRP
In my opinion, it is not sufficient to separate modules by business functions. In the following, cases are explained in which Uncle Bob’s definition of the SRP does not make sense.
1. Hard to articulate
The first problem with Uncle Bob’s definition of the SRP is that it is difficult to apply for real-world developers. What exactly is a business function? Uncle Bob shares an example where he includes C-level executives. He introduces an Employee class where the CFO is responsible for the payment calculation method and the CTO is responsible for the save method. Because two business functions are involved, they should be separated which definitely makes sense.
Nevertheless, applying this in a real-world example is often weird. Uncle Bob uses only C-level positions in his example, but which C-level is, e.g. responsible for the design or the content? It is possible to introduce further business functions like the design but, it is still difficult to allocate all software parts to a special unit.
In my opinion, the idea of separating modules is hard to apply in real-world teams because there is no definition of how to do it. Every team would have to define its own structure which takes time, is still rather confusing, and could change over time. Furthermore, there exists an even more critical shortcoming.
2. Separating by business function is not enough
Imagine an app with a login screen, a home screen, and a profile screen. The design team is responsible for the user interface. According to Uncle Bob’s SRP, these files should not necessarily be separated. They all belong to the same business function. The database, the authentication system, and other services should not be in the same module even if the CTO is “responsible” for all of them.
Responsibilities of one business function
I think these decisions are common sense, nevertheless, it is surprising that Uncle Bob’s definition of the SRP does not address these points. In my experience, it is never wrong to separate modules by business functions but at the same time, it is most often not enough.
How to do it better?
In my opinion, it is better to see a reason to change not in the context of business functions but requirements. Many sources on the internet already address it in this way (Spotify, Youtube). In this case, the definition is quite easy. Can you imagine more than one requirement that causes the module to change? Yes? Then separate it. Do you have a primary color that you use in multiple places in the user interface? Yes? Then separate it from the screens. Do you parse your data directly in your API call? Is it possible that the parsing can change? Yes? Then separate it from the call. This is easy to articulate in your code review.
Therefore, it is useful to change the definition of the reason to change:
A reason to change is a possible requirement that could arise.
Of course, it is up to every developer to what extent she follows these rules. Especially for the UI the SRP is most often not followed completely. Nevertheless, it is common sense that your code quality increases by applying this rule.
Conclusion
The SRP principle defined by Uncle Bob states that “each software module should have one and only one reason to change”. For him, business functions are reasons to change. Applying this has the disadvantages that it is hard to articulate and also not enough to have a reasonable separation. It is more reasonable to see a requirement as a reason to change.
Is it possible that the two requirements cover the same module? Yes? Then separate them to make your software more flexible and improve team collaboration.
Thanks for reading the article! Did you like it? Clap and follow me to stay tuned. Do you have questions? Please let me know in the comments. Any further feedback is highly appreciated!
If you liked the article clap (50x), highlight, comment, and share it. Not only but especially technical articles got disadvantaged by the new Medium Partner Program incentives. If you want to support your favorite (technical) writers on Medium, remember to interact with the articles. You find more information about this here: The New Medium Partner Program is Bad for Quality Writing!
Further information:
Uncle Bob’s book Clean Architecture (affiliate link) includes a description of the SOLID principles. A must-read for every software developer.