SOLID Principles Explained in under 5 minutes
When you're developing a new software component or designing a new solution for a requirement, you need to ensure the solution is designed in such a way that it ensures certain qualities.
When you're developing a new software component or designing a new solution for a requirement, you need to ensure the solution is designed in such a way that it ensures certain qualities.
Flexibility - code must be easy to adapt to new and changing requirements without breaking existing functionality
Maintainability - code must be easy to understand, modify or debug without much effort required
Extensibility - code must be designed such that it’s easy to extend and build new functionalities without having to modify existing stuff.
Testability - code must be easy to create and run tests, without having to make changes just for the sake of it.
To be able to build components with these capabilities, you must ensure that the components are built with certain patterns and principles in mind.
If you’re been in development for sometime, you might have heard the term SOLID principles.
SOLID is actually an acronym for 5 principles. These help us write and create components that are maintainable, extensible and testable.
Let’s look at each of these briefly.
Single Responsibility Principle
S in SOLID stands for Single Responsibility. The principle is stated as follows -
“A component (a class, method or a function) must contain only one function to perform. It must have only one reason to change.”
This principle talks about one of the most common mistakes we do while developing a component or a service -
We generally tend to stuff up a single component (say a class or a method) with all the logic we need it to implement without keeping in mind of its future.
What would happen if some of the dependencies of it need to change? Or how would that component embrace any extension for a part of its functionality.
The core of this principle is that we shouldn’t create such components - these are hard to maintain and are not flexible. Instead create multiple classes that are dedicated to something - a repository that works over only a single Entity, a Service that does only one Domain functionality etc.
Open/Closed Principle
O in SOLID stands for Open/Closed. The principle is stated as follows -
“Any component or module must be such that it is open to extension but closed for modification”
The principle talks about another common mistake we make - making changes to an already released component.
Modifying a component which might be used in other components may result in more problems than before, since we end up testing more components than the one which is actually modified; for the modification shouldn't cause any compatibility issues on the other modules.
The second phrase of the principle states - closed for modification and suggests the first phrase as the solution - open to extension.
The modules should be developed with their probable modification requests in mind and should be designed such that they embrace extension.
Liskov Substitution Principle
L in SOLID stands for Liskov Substitution. The principle states the following -
“The descending classes should behave the same way as the base classes behave. Which means the type S can be used in any place where a type T is used, where S is a subtype of T.”
This principle talks about the core of Object Oriented Programming - Inheritance and substitutability.
When we’re developing components and hierarchies, we must create such that the sub classes are fully substitutable in their base types.
For example, even though we may create hierachy of both Square and Rectangle types, A Square type cannot be substituted for a Rectangle type; although a Square type "is-a" Rectangle type.
Hence we must ensure that components are built such they are substitutable to one another, just inheritance is not enough.
In other words, we shall have a behavior provided by a type be described by means of abstractions and let those abstractions be used where ever the type needs to be utilized.
Interface Segregation Principle
I in SOLID stands for Interface Segregation. The principle states as follows -
“Interfaces must be designed in such a way that they should contain exactly and only those attributes and functionalities which are totally consumed by the client.”
Simply put, the principle talks about the problem of partial interfaces and the plight of clients which have to implement them even though they aren’t needed.
Sometimes we end up creating large interfaces that do a lot of things other than what they’re supposed to represent, while an implementation that has to put logic for only a few of these has to implement all of them nonetheless. What happens is that the implementations leave out some of these methods unimplemented, which may lead to errors.
Hence Interface Segregation states to split Interfaces into smaller and meaningful types which can be fully substituted - which also satisfies Single Responsibility and Liskov Substituion.
Dependency Inversion Principle
D in SOLID stands for Dependency Inversion. The principle states the following -
“High level modules should not depend on low-level modules. Both should communicate by means of abstractions.”
This means that we should avoid direct dependencies of components during communication, and rather have their abstractions be used for the same. The principle also talks about high-level and low-level modules - which are basically the modules which are abstract and close to the user while the Low level are close to the I/O or Hardware.
As we start applying each of these principles to our code, we begin to notice that the code becomes at bit better at each of the above mentioned qualities.
I hope this gives you a brief insight on each of these principles. Share it with someone who may need to understand these.
Learn, practice, succeed (and save) with courses from S$16.98 on Udemy. Click here to know more.