S.O.L.I.D Design Principles



SOLID is one of the most popular sets of design principles promoted by American software engineer and instructor Robert.C.Martin. It is a mnemonic acronym for the first five object-oriented design (OOP) principles. Design principles encourage us to create more maintainable, understandable and flexible software. When applied properly it makes your code more extendable, logical and easier to read. When the developer builds software following the bad design, the code can become inflexible and more brittle, small changes in the software can result in bugs. For these reasons, we should follow SOLID Principles. It takes some time to understand, but if you write code following the principles it will improve code quality and will help to understand the most well-designed software.

SOLID stands for:

S - Single Responsibility

O - Open/Closed Principle

L - Liskov's Substitution Principle

I - Interface Segregation

D - Dependency Inversion


What problems are solved or avoided by applying SOLID?

The software may start with a clean and elegant design but over time they become hard to maintain, often requiring costly redesigns. Robert Martin, who's credited with writing down the SOLID principles, points out some symptoms of rotting design due to improperly managed dependencies across modules:

  • Rigidity: Implementing even a small change is difficult since it's likely to translate into a cascade of changes.
  • Fragility: Any change tends to break the software in many places, even in areas not conceptually related to the change.
  • Immobility: We're unable to reuse modules from other projects or within the same project because those modules have lots of dependencies.
  • Viscosity: When code changes are needed, developers will prefer the easier route even if they break an existing design.

Single Responsibility Principle (SRP)

Single Responsibility Principle was defined by Robert C. Martin as –

"A class should have one and only one  reason to change, meaning that a  class should have only one job"

The Single Responsibility Principle (SRP) is the concept that any single object in object-oriented programming should be made for one specific function. It is a computer-programming principle. It is one of the basic principles most developers apply to build powerful and maintainable software. You can not only apply it to classes, but also to software components and microservices. 

It must have only one responsibility. The fact that the class has a sole responsibility means that it is in charge of doing just one concrete thing, and as a consequence of that, we can conclude that it must have only one reason to change. The argument for the single responsibility principle makes your software easier to implement and prevents unexpected side-effects of future changes. It has a hugely positive impact on the adaptability of code.


Open/Closed Principle (OCP)

Open/Closed Principle was defined by Bertrand Meyer as –

"Objects / entities should be open for extension, but closed for modification"

The Open/Closed Principle represents the "O" of the five SOLID software engineering principles to write well-designed code that is more readable, maintainable, easier to upgrade and modify. Software entities (classes, modules, functions, etc.) be extendable without actually changing the contents of the class you’re extending. If we could follow this principle strongly enough, it is possible to then modify the behavior of our code without ever touching a piece of original code.

We should be able to add new functionality without touching the existing code for the class. This is because whenever we modify the existing code, we are taking the risk of creating potential bugs. It is usually done with the help of interfaces and abstract classes.


Liskov Substitution Principle (LSP)

Liskov Substitution Principle was defined by Barbara Liskov as –

"Every subclass / derived class should be able to substitute their parent / base class"


The Liskov Substitution Principle in practical software development. Liskov's principle is easy to understand but hard to detect in code. The principle defines that objects of a superclass shall be replaceable with objects of its subclasses without breaking the application. That requires the objects of your subclasses to behave in the same way as the objects of your superclass.

An overridden method of a subclass needs to accept the same input parameter values as the method of the superclass. It means you can implement less restrictive validation rules, but you are not allowed to enforce stricter ones in your subclass.



Interface Segregation Principle (ISP)

Interface Segregation Principle was defined by Robert C as –

"Clients should not be forced to implement methods they do not use"

Interface Segregation Principle splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them. It is an important concept while designing and developing applications. ISP is intended to keep a system decoupled and thus easier to refactor, change, and redeploy.

The interface Segregation Principle is one principle which require additional time and effort spent to apply it during the design time and increases the complexity of code. But it produces a flexible design.


Dependency Inversion Principle (DIP)

The dependency Inversion Principle was defined by Robert Martin as –

"Higher level modules should not depend on lower level modules, but they should depend on abstractions"

The dependency inversion principle is a software design principle which provides us the guidelines to write loosely coupled classes. The dependency Inversion Principle consists of two parts:

  1. High-level modules should not depend on low-level modules. Both should depend on abstractions.
  2. Abstractions should not depend on details. Details should depend on abstractions.
The design principle does not just change the direction of the dependency, as you might have expected when you read its name for the first time. In here you get two dependencies:
  1. the high-level module depends on the abstraction, and
  2. the low-level depends on the same abstraction.

 

Conclusion

SOLID is a design principle that plays a very important role during object-oriented design. Software development becomes easy, reusable, flexible, and maintainable using these design principles. It makes your code more extendable, logical and easier to read. SOLID principles can be shared with collaborations, extended, modified, tested, and refactored with fewer complications. 


Reference Sources


Comments