We agree with Sandi Metz when she describes Object Oriented (OO) design as a style guide for arranging code. The so called "OO style guide" is underpinned by a few rules that we have come to know as the SOLID principles.
In this post we will discuss the S in SOLID. We will talk about the significance of this principle and perhaps even look at some practical ideas for applying it.
The S in SOLID refers to the Single Responsibility Principle (SRP). In this post we will explore SRP and highlight some of the easy to miss nuances that it presents.
We like how Matthieu Cneude explains that we should think in terms of sliding scales and not booleans when we talk about SRP. We evaluate the level of SRP present in our software by looking at the coupling and cohesiveness between modules.
"avoid unnecessary coupling and making our modules as cohesive as possible" - Matthieu Cneude
To summarize, SRP is there to remind us to break our software application apart into smaller easy to grasp units of code. We should also group related units of code together whilst limiting dependencies between modules.
The primary goal of design is to reduce the cost of change - Sandi Metz
In her book, Practical Object-Oriented Design, Sandi reminds us that change is unavoidable, and the harder it is to make changes to our applications the more expensive they are to maintain.
As professional software developers we want to write applications that are flexible and adaptable. We cannot foresee the future, but we should design our applications with enough flexibility to accommodate for inevitable future changes.
You might wonder how SRP helps us with writing more flexible and adaptable applications: Let us highlight a few of the benefits that SRP has:
- We don't have to understand the whole system as it is broken down into smaller easier to grasp units.
- Grouping related components together, aka cohesion, makes it easier to know where to make changes in a codebase.
- When modules are well segregated, aka loosely coupled, we can make changes in module A without affecting module B.
- Different teams can work on independent modules without causing code conflicts.
A very simple step we can take to improve the level of applied SRP in our code is to make smaller things. In practice, it means that we should make smaller methods and smaller classes that know as little about each other as possible.
Sandi Metz presents us with a set of rules that serve as a guide for improving the design of our applications. There are 3 rules that are particularly relevant when we talk about SRP:
- No more than 100 lines per class
- Methods may not have more than 5 lines of code
- You may not pass more than 4 parameters per method
If your process includes TDD then your code hopefully goes from red tests to green tests. Once you reach green status only then should you start refactoring. Refactoring is a good time to look for opportunities to improve your code's adherence to the SRP.
"To refactor is to change the arrangement of the code" - Sandi Metz
As you look through the code ask each module what their responsibilities are. Sandi describes an interrogation method where we imaging questioning a specific class. It might seem strange but do give it a try. You can ask the modules/classes questions such as:
- Mr Module what is your responsibility / job?
- Mr Shape class what is your color (if it has a method called color)?
The answers to these question will help you identify when a class is doing more than is required of it. Whenever we use words such as "and" or "or" it may indicate that the class has more than one responsibility. Also, from the example above, it may be a code smell to ask a shape what its color is, but that depends on the context of your particular application.
If you find yourself in a situation where you are not sure whether a class has too many responsibilities or not - then it is safe to wait for more information in the future.
Object oriented design is a style guide that urges us to arrange code in the most flexible and adaptable way possible. The single responsibility principle is one of the object oriented design rules.
Flexible applications are easier and cheaper to maintain than rigid applications. SRP is not a destination, instead it is a journey that we embark on. As we improve our applications adherence to SRP we will reap the rewards of a more cohesive and uncoupled software.
Refactoring presents a great opportunity to increase our app's adherence to the SRP. Don't forget to wait until you have enough information before you separate your app into smaller modules.
If your project is hard to maintain or a pain to work with, then OmbuLabs can help. We are experts at applying the principle of object oriented design so your application can be a joy to work with again.