SOLID principles are a set of five design principles ( mnemonics acronym known as S.O.L.I.D ) in the object-oriented paradigm. They were first introduced by Robert C Martin. These concepts are in practice since early 2000 and still applicable to the modern design process.
In this article, we will get brief details of SOLID principles, their benefits, and a high-level glimpse of each SOLID principles.
1. SOLID principles benefits
When applied together, these principles become a guideline to develop robust software products which are easily maintainable, testable, scalable and extensible.
Not only that, design principles help in reducing errors, easy code refactoring, make the code more efficient and helpful in achieving iterative development methodology – for example agile.
2. Design Principle or Design Pattern?
When we talk about design principles, most developers refer to the terms Design Pattern and Design Principles interchangeably. However, there is a difference between the two.
Design Principles are more on suggesting the right and the wrong way of designing a particular system. In short, they just denote what to do for a particular problem statement as a solution.
Design Patterns on the other end represent a reusable solution to commonly occurs problems. Design pattern exactly shows how to solve a particular problem in a given design context by suggesting clear methodologies.
The difference between Design Principles and Design Patterns lies in one sentence – Desing Principle talks on What part while Design Patterns talk about How part.
3. SOLID Principles details
SOLID principles are most popular among the set of design principles in the object-oriented world. This article gives a brief explanation of each of these principles. I will be writing a separate article dedicated to explaining each principle with more in-depth details.
The SOLID principles cover the following five design principles. Each letter of this acronym represents the design principle name. This is how the S.O.L.I.D is formed in a joint way.
- S – Single Responsibility principle
- O – Open-closed principle
- L – Liskov substitution principle
- I – Interface Segregation principle
- D – Dependency Inversion principle
We will see a brief about each of these rules to understand why they are so important to adopt for a good developer.
3.1 S – Single Responsibility Principle
The Single Responsibility principle or in short SRP talks on:
A class should have one and only one reason to change
This means a class should do a single responsibility or job. While designing the software product, often we write a Class that handles multiple things.
At first glance, you might think this is a good idea. However, this seems true until you reach a certain level of complexity. When the application is growing, you will really feel it difficult to maintain it if you don’t follow this principle.
Adding multiple functionalities in a single class will introduce coupling between the functionalities. In this scenario, changing one would affect and may break several other functionalities. This required additional effort to fully test the code before deploying to production and difficult to maintain every change.
3.2 O – Open-closed Principle
The Open-closed principle talks more about the structural part of your application. It states:
Your program should be open for extension and close for modification
Here the program is referred to as an object or an entity. A programming language like Java, this refers to a class – a basic building block of an application.
In the context of Java (or any other object-oriented programming language), this principle state that the class should be design in a way that it’s easily extensible at the same time restricted to modify itself for introducing new features or functionality.
This principle gives assurance that no one can change already tried, tested and fully functional code. To adopt this principle, you should write code in an abstract way to accommodate the further change in the form of extending the existing code.
3.3 L – Liskov Substitution Principle
The Liskov Substitution Principle (known as LSP) focuses on the relationship between superclass and subclass. In conjunction with the open-close principle, Liskov substitution principle talks about:
The object of superclass should be substituted by the object of its subclass
This should happen without breaking an application. This mean, the object of the subclass should behave exactly in the same way as its superclass object. To achieve this, you need to make sure about the following things
- The overridden method should take a similar parameter as defined in the superclass.
- Make sure the subclass impose less restrictive validation rule than the superclass.
- The return type of the method in a subclass must be a subtype of the return value of the method in the superclass.
This rule can be verified by calling all the subclass instance to make sure the application works without any glitch and performance issue.
3.4 I – Interface Segregation Principle
In the same context of Single Responsible Principle, this principle talks about:
A client should not implement an interface if it doesn’t use it
In other words, the design should not force a client to implement the interface it doesn’t really need. This mostly occurs when the interface contains more than one un-related methods.
To achieve the solution with this principle, you should break a single interface to multiple interfaces with either hierarchical or independent manner. In short many, small and client-specific set of interfaces are more preferable than big or fat interface with many methods.
3.5 D – Dependency Inversion Principle
The Dependency Inversion Principle gives a suggestion of using abstraction in place of concrete implementation. It talks about
- High-level modules should not depend on low-level modules and both should depend on abstraction.
- Details or concrete implementation should depend on abstraction rather than an abstraction depends on details.
Seeing the name of this principle, one can think that this principle asks to change the direction of dependency but in reality, it’s not. Instead, it suggests managing the dependency between high and low-level modules in an abstract way.
The SOLID principles that we talk here are inter-related with each other. For example, if you apply Open-closed principle where you make your class open for extension and close for modification, you need some sort of abstraction in between. Again that abstraction should follow the Liskov Substitution Principle (LSP).
Then ultimately you need to design the high and low-level modules in a way that they interact with each other in an abstract way. That is what Dependency Inversion Principle is. In short, the Dependency Inversion Principle asks to separate the modules with each other and at the same time, do bind them together in an abstract way.
Design principles greatly help designers to enhance usability, influence and improve the perception, increase the confident level, boots adoption capabilities. All these qualities will ultimately help to build a robust application which is easily maintainable, testable, reusable and extendable.
SOLID Principles are among the most popular set of design principles which must be considered while designing a system. Adopting these principles with continuous usage will surely help to build sustainable software products.
As an exercise, you can find some real-world use cases where you can apply these principles to understand the concepts in more detail.