SOLID
Design principles encourage us to create more maintainable, understandable, and flexible software.
Consequently, as our applications grow in size, we can reduce their complexity and save ourselves a lot of headaches further down the road!
Single-responsibility
There should never be more than one reason for a class to change or every class should have only one responsibility
That is, a class should only have one responsibility. Furthermore, it should only have one reason to change.
Benefits
-
Testing
A class with one responsibility will have far fewer test cases
-
Lower coupling
Less functionality in a single class will have fewer dependencies
-
Organization
Smaller, well-organized classes are easier to search than monolithic ones.
Open–closed
Software entities should be open for extension, but closed for modification
In doing so, we stop ourselves from modifying existing code and causing potential new bugs.
Benefits:
-
Error Prevention
Minimize the possibilities of error by not modifying existing classes.
-
Functionality Extension
Easily add new functionalities by adding new classes wherein no current functionality depends on the new classes.
-
Responsibility Segregation
Promote the Single Responsibility Principle
-
Class Testing
Unit test each class
Liskov substitution
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it
That is, if class A is a subtype of class B, we should be able to replace B with A without disrupting the behavior of our program.
Benefits
-
Code reusability
Allows creating a set of related classes that can be used interchangeably without modifying the code. This makes it easier to reuse code and can save us time when we’re developing new features.
-
Easier maintenance
Avoids introducing conditional logic or type checking to handle different subclasses. This makes the code more readable and easier to maintain. It also reduces the risk of introducing bugs or breaking changes when we add or modify subclasses.
-
Reduced coupling
Reduces the dependency between classes and make them more loosely coupled. This means that changes in one class will not affect other classes that depend on it. This also makes the code more flexible and adaptable to changing requirements
Interface segregation
Many client-specific interfaces are better than one general-purpose interface
That is, larger interfaces should be split into smaller ones. By doing so, we can ensure that implementing classes only need to be concerned about the methods that are of interest to them.
Dependency inversion
Depend upon abstractions, not concretions
This way, instead of high-level modules depending on low-level modules, both will depend on abstractions.
Benefits
-
Decoupling
The code becomes more modular and less tightly coupled. This makes it easier to maintain, extend, and test the code. It also reduces the impact of changes in one module on other modules
-
Reusability:
The code becomes more reusable and adaptable. High-level modules can use different low-level modules that implement the same abstraction without modifying the code. This allows for swapping implementations, mocking dependencies, and supporting different scenarios
-
Inversion of control
The flow of the application is inverted from low-level modules to high-level modules. High-level modules define the abstractions and own the interfaces, while low-level modules provide the implementations and depend on the interfaces. This gives more power and flexibility to the high-level modules
Top comments (0)