What are SOLID design principles?
SOLID design principles are a set of rules that guide developers in creating more maintainable, flexible and scalable software. These principles are essential for implementing clean architectures. Although there are five in total, this time we will focus on three: the single responsibility principle (S), the open and closed principle (O) and the dependency inversion principle (D).
What is the single liability principle?
The single responsibility principle, represented by the letter "S" in SOLID, states that a module must have only one reason to change. A module can be a file or a class, and this principle helps us avoid combining multiple responsibilities in one place.
Practical example:
Imagine a JavaScript application that receives requests via the POST method, performs validations, and stores data in a database. Currently, this code has three reasons to change: communication (HTTP), data validation and database access.
function handleRequest(req) { validateRequest(req); saveToDatabase(req);}
function validateRequest(req) { }
function saveToDatabase(req) { }
Instead of combining these tasks, the single responsibility principle suggests that we should separate them into functions or classes, each with its own responsibility.
How to apply the open-closed principle?
The open and closed principle, symbolized by the letter "O", suggests that a module should be open to extend but closed to modify. This implies that, instead of altering the existing code by adding new functionality, new features should be integrated without modifying the existing structure.
Practical example:
In a system with chained conditional structures for different cities:
if (city === 'Cali') { processCali();} else if (city === 'Lima') { processLima();}
It is preferable to structure it to allow extensibility:
{class CityProcessor { process() {}} }
class CaliProcessor extends CityProcessor { process() { }} }
class LimaProcessor extends CityProcessor { process() { }}
By creating specific classes, we can add new cities by applying inheritance, avoiding modifying existing code and improving maintainability.
What is the dependency inversion principle?
The dependency inversion principle, corresponding to the letter "D", holds that high-level modules should not depend on low-level modules. Rather, both should depend on abstractions, since details should depend on abstractions and not the other way around.
Detailed explanation:
- Presentation and Data Access: these are low-level modules. They tend to change more frequently.
- Domain (Business Logic): This is a high-level module. It must remain independent of specific implementation details, such as database or user interface changes.
Use of dependency injection:
Dependency injection is crucial to implement this principle, as it allows high-level modules to depend not directly on low-level implementations, but on interfaces or abstractions.
By using these principles, developers can achieve more robust systems, with controlled growth and sustainability over time, starting with a robust and logical structure from the beginning of the projects. Continue exploring these concepts to further hone your programming skills!
Want to see more contributions, questions and answers from the community?