SOLID principles in Simple Words

Prasanna Brabourame
5 min readMay 24, 2022
  • S — Single Responsibility Principle
  • O — Open - Closed Principle
  • L — Liskov’s Substitution Principle
  • I — Interface Segregation Principle
  • D — Dependency Inversion Principle

▶️ 𝗦𝗶𝗻𝗴𝗹𝗲 𝗥𝗲𝘀𝗽𝗼𝗻𝘀𝗶𝗯𝗶𝗹𝗶𝘁𝘆 𝗣𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲

𝘉𝘳𝘦𝘢𝘬 𝘥𝘰𝘸𝘯 𝘣𝘪𝘨 𝘤𝘭𝘢𝘴𝘴𝘦𝘴 𝘸𝘪𝘵𝘩 𝘮𝘢𝘯𝘺 𝘫𝘰𝘣𝘴 𝘪𝘯𝘵𝘰 𝘴𝘮𝘢𝘭𝘭𝘦𝘳 𝘤𝘭𝘢𝘴𝘴𝘦𝘴 𝘸𝘪𝘵𝘩 𝘰𝘯𝘦 𝘫𝘰𝘣.

Yeah… I don’t think so.

Following this leads to an explosion of little classes. Then you have to name them all (one of 2 or 3 hardest problems in computing, depending on who you ask). Then organize and orchestrate them. Instead of a class getting a little bloated, the entire codebase gets a LOT bloated.

There is some benefit to breaking things apart, but it has to be balanced by the benefits of cohesion.

Brief : This principle states that “a class should have only one reason to change” which means every class should have a single responsibility or single job or single purpose. Take the example of developing software. The task is divided into different members doing different things as front-end designers do design, the tester does testing and backend developer takes care of backend development part then we can say that everyone has a single job or responsibility. Most of the time it happens that when programmers have to add features or new behavior they implement everything into the existing class which is completely wrong. It makes their code lengthy, complex and consumes time when later something needs to be modified. Use layers in your application and break God classes into smaller classes or modules.

Score: 1 out of 5

▶️ 𝗢𝗽𝗲𝗻-𝗖𝗹𝗼𝘀𝗲𝗱 𝗣𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲

𝘍𝘪𝘯𝘥 𝘸𝘢𝘺𝘴 𝘵𝘰 𝘢𝘥𝘥 𝘧𝘶𝘯𝘤𝘵𝘪𝘰𝘯𝘢𝘭𝘪𝘵𝘺 𝘸𝘪𝘵𝘩𝘰𝘶𝘵 𝘮𝘰𝘥𝘪𝘧𝘺𝘪𝘯𝘨 𝘦𝘹𝘪𝘴𝘵𝘪𝘯𝘨 𝘤𝘰𝘥𝘦. 𝘌𝘨. 𝘸𝘳𝘢𝘱 𝘦𝘹𝘪𝘴𝘵𝘪𝘯𝘨 𝘤𝘭𝘢𝘴𝘴 𝘪𝘯𝘵𝘰 𝘢 𝘯𝘦𝘸 𝘰𝘯𝘦, 𝘰𝘳 𝘶𝘴𝘦 𝘱𝘰𝘭𝘺𝘮𝘰𝘳𝘱𝘩𝘪𝘴𝘮.

Or how about, if it makes sense to modify an existing class, then modify it. If it makes sense to create a specialized version, then wrap it.

If you are afraid that modifying a class will break your codebase, you have bigger problems to worry about than SOLID principles.

Brief : This principle states that “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification” which means you should be able to extend a class behavior, without modifying it. Suppose developer A needs to release an update for a library or framework and developer B wants some modification or add some feature on that then developer B is allowed to extend the existing class created by developer A but developer B is not supposed to modify the class directly. Using this principle separates the existing code from the modified code so it provides better stability, maintainability and minimizes changes as in your code.

Score: 2 out of 5

▶️ 𝗟𝗶𝘀𝗸𝗼𝘃’s 𝗦𝘂𝗯𝘀𝘁𝗶𝘁𝘂𝘁𝗶𝗼𝗻 𝗣𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲

𝘐𝘧 𝘢 𝘤𝘩𝘪𝘭𝘥 𝘤𝘭𝘢𝘴𝘴 𝘰𝘷𝘦𝘳𝘳𝘪𝘥𝘦𝘴 𝘱𝘢𝘳𝘦𝘯𝘵’𝘴 𝘮𝘦𝘵𝘩𝘰𝘥, 𝘪𝘵 𝘴𝘩𝘰𝘶𝘭𝘥 𝘧𝘶𝘯𝘥𝘢𝘮𝘦𝘯𝘵𝘢𝘭𝘭𝘺 𝘥𝘰 𝘵𝘩𝘦 𝘴𝘢𝘮𝘦 𝘵𝘩𝘪𝘯𝘨, 𝘯𝘰𝘵 𝘴𝘰𝘮𝘦𝘵𝘩𝘪𝘯𝘨 𝘤𝘳𝘢𝘻𝘺.

So if you have a “𝚛𝚎𝚚𝚞𝚎𝚜𝚝𝙿𝚊𝚜𝚜𝚠𝚘𝚛𝚍𝚁𝚎𝚜𝚎𝚝” method that accepts an “𝚊𝚌𝚌𝚘𝚞𝚗𝚝”, you can call it with a “𝚌𝚞𝚜𝚝𝚘𝚖𝚎𝚛” or “𝚊𝚍𝚖𝚒𝚗” without worry.

This is a good one! I completely agree.

Brief : The principle was introduced by Barbara Liskov in 1987 and according to this principle “Derived or child classes must be substitutable for their base or parent classes“. This principle ensures that any class that is the child of a parent class should be usable in place of its parent without any unexpected behavior. You can understand it in a way that a farmer’s son should inherit farming skills from his father and should be able to replace his father if needed. If the son wants to become a farmer then he can replace his father but if he wants to become a cricketer then definitely the son can’t replace his father even though they both belong to the same family hierarchy. One of the classic examples of this principle is a rectangle having four sides. A rectangle’s height can be any value and width can be any value. A square is a rectangle with equal width and height. So we can say that we can extend the properties of the rectangle class into square class. In order to do that you need to swap the child (square) class with parent (rectangle) class to fit the definition of a square having four equal sides but a derived class does not affect the behavior of the parent class so if you will do that it will violate the Liskov Substitution Principle.

Score: 5 out of 5

▶️ 𝗜𝗻𝘁𝗲𝗿𝗳𝗮𝗰𝗲 𝗦𝗲𝗴𝗿𝗲𝗴𝗮𝘁𝗶𝗼𝗻 𝗣𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲

𝘐𝘯𝘴𝘵𝘦𝘢𝘥 𝘰𝘧 𝘣𝘪𝘨 𝘪𝘯𝘵𝘦𝘳𝘧𝘢𝘤𝘦𝘴, 𝘤𝘳𝘦𝘢𝘵𝘦 𝘢 𝘭𝘰𝘵 𝘰𝘧 𝘯𝘢𝘳𝘳𝘰𝘸 𝘭𝘪𝘵𝘵𝘭𝘦 𝘪𝘯𝘵𝘦𝘳𝘧𝘢𝘤𝘦𝘴. 𝘚𝘰 𝘸𝘩𝘦𝘯 𝘺𝘰𝘶 𝘮𝘢𝘬𝘦 𝘤𝘭𝘢𝘴𝘴𝘦𝘴, 𝘺𝘰𝘶 𝘤𝘢𝘯 𝘪𝘮𝘱𝘭𝘦𝘮𝘦𝘯𝘵 𝘰𝘯𝘭𝘺 𝘸𝘩𝘢𝘵 𝘺𝘰𝘶 𝘯𝘦𝘦𝘥.

Basically, like the SRP for interfaces.

It’s a bit better than SRP since there is less to implement. But there is still the issue of naming and keeping track of all these little things (unless you can have ad-hoc types, like in typescript).

Brief : This principle is the first principle that applies to Interfaces instead of classes in SOLID and it is similar to the single responsibility principle. It states that “do not force any client to implement an interface which is irrelevant to them“. Here your main goal is to focus on avoiding fat interface and give preference to many small client-specific interfaces. You should prefer many client interfaces rather than one general interface and each interface should have a specific responsibility. Suppose if you enter a restaurant and you are pure vegetarian. The waiter in that restaurant gave you the menu card which includes vegetarian items, non-vegetarian items, drinks, and sweets. In this case, as a customer, you should have a menu card which includes only vegetarian items, not everything which you don’t eat in your food. Here the menu should be different for different types of customers. The common or general menu card for everyone can be divided into multiple cards instead of just one. Using this principle helps in reducing the side effects and frequency of required changes.

Score: 3 out of 5

▶️ 𝗗𝗲𝗽𝗲𝗻𝗱𝗲𝗻𝗰𝘆 𝗜𝗻𝘃𝗲𝗿𝘀𝗶𝗼𝗻 𝗣𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲

𝘐𝘯 𝘧𝘶𝘯𝘤𝘵𝘪𝘰𝘯 𝘱𝘢𝘳𝘢𝘮𝘦𝘵𝘦𝘳𝘴, 𝘢𝘤𝘤𝘦𝘱𝘵 𝘪𝘯𝘵𝘦𝘳𝘧𝘢𝘤𝘦𝘴 𝘪𝘯𝘴𝘵𝘦𝘢𝘥 𝘰𝘧 𝘤𝘭𝘢𝘴𝘴𝘦𝘴.

Out of all the SOLID-s, this one most clearly deals with the specifics of a language like JAVA.

But if we expand it to mean “𝘢𝘤𝘤𝘦𝘱𝘵 𝘦𝘹𝘢𝘤𝘵𝘭𝘺 𝘸𝘩𝘢𝘵 𝘺𝘰𝘶 𝘯𝘦𝘦𝘥 𝘢𝘯𝘥 𝘯𝘰𝘵𝘩𝘪𝘯𝘨 𝘦𝘭𝘴𝘦”, then it has merit.

Eg. if you want to print a dog’s name and age, accept anything that has “𝚗𝚊𝚖𝚎” and “𝚊𝚐𝚎” props, don’t worry about whether it’s a dog or a cat. Makes testing a lot easier.

Brief : This principle suggest that “classes should depend on abstraction but not on concretion”. What does it mean that we should be having object of interface which helps us to communicate with the concrete classes. What do we gain from this is, we hide the actual implementation of class A from the class B. So if class A changes the class B doesn’t need to care or know about the changes.

Score: 4 out of 5

--

--

Prasanna Brabourame

AI Engineer | Researcher | Open Source Enthusiast | Full Stack Dev | Blockchain | DEVOPS | Learner | Blogger | Speaker | Tech Geek