The following is one of the five fundamental principles which can help you to write a better, cleaner, and maintainable code. These principles were introduced by “Uncle” Bob C. Martin and the acronym “S.O.L.I.D.” was introduced by Michael Fathers. The original main source of the information can be found on the personal blog of Uncle Bob.
First, I would do a general overview and later I will be going into the small details.
Lets see what the acronym “S.O.L.I.D.” means:
- Single Responsibility Principle (SRP): “A class should have only a single responsibility… There should never be more than one reason for a class to change”.
- Open / Close Principle (OCP): Open for extension; however, closed for modification.
- Liskovs Substitution Principle (LSP): Without altering the correctness of the program, objects should be replaceable with instances of their sub-types.
- Interface segregation Principle (ISP): Instead of a huge fat general-purpose interface, we should create many client-specific interfaces.
- Dependency Inversion Principle (DIP): “Depend upon Abstractions. Do not depend upon concretions.”
Single Responsibility Principle (SRP)
“A class should have only a single responsibility… There should never be more than one reason for a class to change”… what does that means? This mean two separate things:
- Your class should concentrate on doing only one thing and that one thing should be its only responsibility.
If your class do more than one thing, which means more than one responsibility, you should break it down in smaller classes in which each takes care of only one responsibility.
- If that one only thing changes, then you are allowed to change the structure of such class, else don’t touch it.
In other words, lets say you wrote a class have the responsibility of using the modem and takes care of the protocol of communication, you should brake this into two classes. One class will take care of using the modem, the other class will take care of the protocol of communication.
Why? The first reason is maintenance. Since each class only concentrates on one responsibility, it will be easier to maintain them plus they will be smaller on size. The second reason is re-usability. In this case, we could have a different hardware than a modem, lets say Bluetooth, and don’t need to rewrite again the communication protocol.
If out of the blue, you have more than one type of communication protocol (TCP, UDP, etc.) then perhaps you want to separate this class into small classes in which each class takes care of one type of protocol.
By now, you must be getting the idea.
Single Responsibility Principle (SRP) and Test-Driven Development (TDD)
Test-Driven Development and Single Responsibility Principle go hand by hand pretty nicely.
For those who don’t know, the idea of Test-Driven Development is to follow a cycle that works as follow:
Step 1: Write a test case first.
Step 2: Write the minimum code to pass that test case.
Step 3: Restructure your existing code without changing its external behavior.
Step 4: Go to Step 1 and apply all steps with the next feature.
So, if you write test cases for small classes that have a single responsibility, your classes will become solid blocks that you can use while knowing that they pass all the tests you designed before.
Single Responsibility Principle (SRP) and Model-View-Controller (MVC)
The Model-View-Controller is a framework in which you separate user interface (View), from the business logic (Controller) and the data (Model). In this way, you should be able to reuse these components and make a better and cleaner code. However, I found out that what is being called a controller is actually being used as a “View Controller” which holds business logic and controls the view behavior. This can become a huge mess. Therefore, I would advice that you keep the business logic separated from the view and the follow is an example:
In this way, the view takes care of the interaction with the user, the view controller, takes cares of any changes that must be done to the view, the controller is the business logic, and the model is the data. This should follow the idea of Single Responsibility Principle and allow for an easier application of Test-Driven Development.