Programming with SOLID Principles
- Single Responsibility Principle
- Open/Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency of Inversion Principle
- Conclusion
Introduced by software engineer Robert Martin in the early 2000s, the five basic principles for good object-oriented programming design make code-bases more clean and maintainable. They also serve as an overall strategy to agile programming.
To my surprise, I discovered that many developers do not know these principles, so the purpose of this article is to introduce you to them if you are unaware or act as a quick review reference otherwise. The principles discussed here allow you to create more flexible, robust, and reusable code.
Single Responsibility Principle
All too often, I have seen classes in applications that are thousands of lines long, making them difficult to extend, much less maintain. Classes this large that do too many things at once end up with a fragile and rigid architecture, making them much more breakable and not easily extendable.
The Single Responsibility (SR) principle resolves this problem by stating that each class should have one only reason to change (a single responsibility).
Having a lone responsibility decreases the risk of introducing new bugs and breaking the code. A class can have multiple methods, but these methods should work together to meet that single responsibility.
Another important thing this principle does is create looser coupling between other classes because the dependencies on others are limited.
Take a look at the following example class code:
public class Rectangle { void draw(){ // code here } void getArea(){ // code here } }
In this example, the Rectangle class violates the SR principle because it has two responsibilities: drawing the rectangle and computing the area. One class in the application might need to draw the rectangle; another class might need to only compute the area.
Changes to one of the methods can introduce a bug that breaks the other responsibility. The class that needs to draw a rectangle might no longer be able to do so because of a problem that happened when changing the getArea() method. I have seen problems like these countless times in real-world code.
A better design is to separate the responsibilities into two separate classes so that drawing a rectangle is handled by one class and computing the area is handled by another. If a change is made that breaks the compute area code, it no longer affects drawing a rectangle.