Lets Solidify Your “SOLID” Principle Concept.

Noymul Islam Chowdhury Shorot
5 min readNov 10, 2019
pic is taken from https://team-coder.com/solid-principles/

If you are a software developer or coder and if you ever tried to read articles or books about good design principles then you might have come across the word SOLID many times. If you don’t or your ideas are vague about SOLID then this article is for you. I will try to explain SOLID — “ An acronym of five important design principles” to you.

S — Single Responsibility Principle.

So the first principle states that your class or component should be responsible for doing only one thing. Look at the bellow example to understand it a bit better.

Here we have a Employee class which has several methods. So what do you think now? Does it satisfy the single responsibility principle? Actually it doesn’t! Why? Because an Employee class shouldn’t be responsible for calculating salary. Perhaps we should have a Salary class which will do that for us. Don’t burden your class by forcing it to do someone else’s work.

O — Open /Closed Principle.

Open/Closed principle states that an software entity should be open for extension but close for modification. So, what does that mean? Let’s see the bellow example.

So here we have an Area class which deals with different geometric shapes and calculates their area. Seems pretty easy and perfect. But there is a problem! Suppose tomorrow we want to add another shape in our program. Suppose we want to add Square shape. So now we have to add that shape in our shapes array and pass it to GetArea method. And then we also need to add proper logic to calculate its area. That means we need to modify the GetArea method each time we add new shape. And this is what we should be refrained from. Perhaps what we could do is make each shape a separate concrete class and make IShape an interface that contains GetArea method. All shapes have to implement the IShape interface. Each concrete shape will implement the GetArea method with its own logic. So if tomorrow we need to add another shape say Trapezium, all we have to do is implement the IShape interface in our Trapezium class. This is how we can extent the behavior of our program without modifying the existing code.

L — Liskov Substitution Principle.

Liskov substitution principle states that parent should be replaced by child without altering any of its behaviors. One well known example is the rectangle-square example. Square is one type of rectangle. Because of the IS-A relationship between them you might want to inherit Square class from the Rectangle class. Imagine Rectangle class has SetWidth and SetHeight methods to set its width and height. Now if you use Rectangle reference to point Square then things may become clumsy. Why? Because SetWidth and SetHeight don’t make any sense when you are using them for Square. Setting one would change the other. And so Square fails the Liskov substitution test. Don’t always use inheritance to save some lines of codes. Before using inheritance test it with the L.S.Principle.

I — Interface Segregation Principle.

We should not make our interfaces unnecessarily fat. What I meant by that is client should not be forced to implement methods that they don’t use. Consider the following example.

So we have a interface named IAnimal which contains a method called Feed. Tiger and Eagle are two separate classes that implement IAnimal interface. Now tomorrow suppose we add a new method in our IAnimal interface named Milk. Now milk is a term that is only used for mammal. As Eagle is not a mammal so the Milk method is irrelevant for Eagle class. So what we can do is break the IAnimal interface in the following way.

So we are introducing a new interface IMammal which contains Milk method and inherits IAnimal. Now Tiger should implement the IMammal interface and Eagle should implement IAnimal only.

D — Dependency Inversion Principle.

To understand this principle first let us consider a scenario. Suppose we are using MySql as our database. And we have a class named MySql which contains some methods to perform different db operations. Our client code solely depends on this MySql class. We instantiated it in different places of our code base to perform necessary db operations. But tomorrow if we decide that we will no longer use MySql and we may shift to MongoDb or anything else? Then what should we do? Because our whole code base is tightly coupled with MySql class and to adopt this change we have to refactor it a lot! And this is where DIP comes in. It suggests that high-level module should not depend on low-level module. Instead they both should depend on an abstraction. It means our client code shouldn’t depend directly on MySql class. It should depend on an interface say IDB which contains several methods and MySql class should implement that interface. So that in future if we decide to switch to MongoDB then all we need to do is implement the IDB interface in our Mongo class. Client code need not to know if it is dealing with MySql or MongoDB!

--

--