Learn about SOLID Principles
In this lesson, we will learn the following.
- SOLID Acronym and Introduction
- SOLID Design Principles
- Why do we need to adapt SOLID
Let’s now discuss SOLID principles in details
Acronym
SOLID | Acronym | Short Description |
S | SRP | Single Responsibility Principles |
O | OCP | Open Closed Principles |
L | LSP | LISKOV substitution principles |
I | ISP | Interface Segregation Principles |
D | DIP | Dependency Inverse Principles |
Introduction
- SOLID Principles are the design principles that enable us to manage most of the software design problems. These principles are intended to make software design more understandable, flexible, and maintainable.
- These five principles are a subset of many other principles promoted by Robert C. Martin (Uncle Bob). Their acronyms were first introduced by Michael Feathers.
The motivation of using SOLID
- Maintainability
- Testability
- Flexibility and Extensibility
- Parallel Development
- Loose Coupling
Single Responsibility Principles
Uncle Bob expresses the principle as “A class should have only one reason to change”. Everything in a class should be related to a single purpose. There can be many members in a class as long as they are related to a single responsibility. With the help of SRP, classes become smaller and cleaner. Some examples of responsibilities to consider that may need to be separated include –
- Persistence
- Validation
- Notification
- Error Handling
- Logging
- Class Selection / Instantiation
- Formatting
- Parsing
- Mapping
Interface Segregation Principle
This principle was first used and formulated by Robert C. Martin (Uncle Bob) while consulting for Xerox.
- No client should be forced to depend on methods they do not use.
- One heavy interface needs to be split into many smaller and relevant interfaces so that the clients can know about the interfaces that are relevant to them.
We will take a case study that Uncle Box resolved for Xerox.
Problem
- Xerox had created a new printer system that could perform a variety of tasks such as stapling and faxing along with regular printing tasks.
- The software for this system was created from the ground up.
- Modifications and Deployment to the system became more complex
The design problem was that a single job class was used for almost all of the tasks.
Solution
- One large job class is segregated to multiple interfaces depending on the requirements
Actually, if you add methods that shouldn’t be there, the classes implementing the interface will have to implement those methods as well. That is why; the client shouldn’t be forced to depend on interfaces that they don’t use. ISP is intended to keep a system decoupled and thus easier to refactor, change, and deploy. Refer to the .NET code snippet attached with this tutorial. If you look at the previous section, you could see that the interface has been segregated based on the requirements.
Open Closed Principles
This section covers
- Open closed principle
- Implementation guidelines
- Example
Open Closed principle
- Software entities such as classes, modules, functions, etc. should be open for extension but closed for modification.
- Any new functionality should be implemented by adding new classes, attributes, and methods, instead of changing the current ones or existing ones.
- Bertrand Meyer originated the term OCP
- Robert C. Martin (Uncle Bob) considered this as the most important principle of object-oriented design
Implementation Guidelines
- The simplest way to apply OCP is to implement the new functionality on new derived classes.
- Allow the client to access the original class with the abstract interface.
Why OCP? If not followed:
- End up testing the entire functionality
- QA team need to test the entire flow
- Costly process for the organization
- Breaks the single responsibility as well.
- Maintenance overheads increase in the classes.
Example Refer to the .NET code snippet attached, an Employee class calculating bonus based on the employee types (Permanent and Contract)
Liskov Substitution Principle
This section covers
- Liskov Substitution principle
- Implementation guidelines
- Example
Liskov Substitution principle
- “S is a subtype of T, and then objects of type T may be replaced with an object of type S”
- Derived types must be completely substitutable for their base types.
- LSP is a particular definition of a sub-typing relation, called (strong) behavioral sub-typing.
- Introduced by Barbara Liskov
- Extension of Open closed principle
Implementation Guidelines
- No new exception can be thrown by the sub-type.
- Client should not know which specific sub-type they are calling
- New derived classes just extend without replacing the functionality of old classes.
It may be confusing, but this can be achieved through a simple example. Please refer to the attached .NET sample (LSP folder)
Dependency Inversion Principle
Here, let us cover:
- Dependency Inversion Principle
- Understanding the intention of DIP usage.
Dependency Inversion Principle
- This is also known as DIP
- Introduced by Robert C. Martin
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstraction should not depend on details. Details should depend on abstraction.
- The interaction between high level and low-level modules should be thought of as an abstract interaction between them
Intention of usage If you look at the traditional layered approach-
Presentation Layer => Business Layer => Data Access Layer Here, the high-level module depends on the low-level module. In order to resolve this coupling issue, we will be introducing an interface layer through which different layers can interact.
Business Layer => Interface Repository =>this will be implemented in the Data Access Layer Business layer would be communicating with the Data Access Layer via the interface. This approach will help us to test each module independently.
Adapter design pattern is one of the examples of DIP usage. We are not going to discuss the adapter design pattern in this article.