Do you know the principles of education or medicine? Sure you do, after all, they are quite popular.
But did you ever think that maybe developers also have their own principles?
Today we want to tell you about solid principles and how they are applied in software development to make developers’ work easier.
Table of Content
What are solid principles?
It’s a popular set of design principles used in object-oriented software development. SOLID is an acronym for five key design principles:
- Single Responsibility Principle.
- Open-closed principle.
- Liskov substitution principle.
- Interface segregation principle.
- Dependency inversion principle.
All five are commonly used by software engineers and provide important advantages to developers, hence their importance for this area of work.
The solid principles were developed by Robert C. Martin in a 2000 essay entitled Design Principles and Design Patterns. Although the acronym was later coined by Michael Feathers.
In his essay, Martin recognized that successful software would change and develop, and as it changed, it became increasingly complex.
Without good design principles, Martin warns that software becomes rigid, brittle, and immobile. SOLID principles were developed to combat these problematic design patterns.
What are their objectives at the time of implementation?
The overall goal of SOLID principles is to reduce dependencies so that engineers can change one area of the software without affecting others.
In addition, they are intended to make designs easier to understand, maintain and extend. Ultimately, using these design principles makes it easier for software engineers to avoid problems and create software that is adaptable, efficient, and agile.
Although the principles have many advantages, following them often leads to writing longer and more complex code.
This means that it can lengthen the design process and make development a bit more difficult. However, this extra time and effort is worth the work because they make the software much easier to maintain, test, and extend.
OK, but it should be made clear that these principles are not a solution and will not avoid design problems.
That said, the principles have become popular because, if followed correctly, they improve code readability, maintainability, design patterns and testability.
In today’s environment, all developers should know and use these principles.
The 5 solid principles
Now that we know a little more about the solid principles and their objectives at the time of implementation, it’s time to know which solid principles developed by Martin are.
1. Single-Responsibility Principle.
Robert Martin summarizes this principle well by stating that a class should have one, and only one, reason to change.
Following this principle means that each class only does one thing and that each class or module is only responsible for one part of the software’s functionality. In short, each class must solve only one problem.
This first principle is basic and essential for the development of different software and, because of this, most developers already use the single responsibility principle to build their different lines of code. It can be applied to software components and microservices.
Using this principle makes the code easier to test and maintain, makes the software easier to deploy, and helps to avoid unforeseen side effects of future changes.
This simple, but useful principle avoids potential bugs, which translates into less time-consuming work for the developer.
To ensure that you are following this principle in development, consider using an automated check in the construction to limit the scope of classes.
This check is not a foolproof way to make sure you are following the single responsibility principle, but it can be a good way to make sure that classes are not violating this principle.
2. Open-Closed Principle.
The idea of the open and close principle is that existing, well-tested classes will have to be modified when something needs to be added. Let’s say you forgot to add a line of code, you can do it.
However, adding code can lead to problems or bugs, the result? More work. Instead of changing the class, just extend it. With that goal in mind, Martin summarizes this principle by extending the behavior without modification.
Following this principle is essential for writing code that is easy to maintain and review. You can say that you have complied with this principle if it meets the following 2 characteristics.
- Open to extension, which means that the behavior of the class can be extended.
- Closed for modification, which means that the source code is fixed and cannot be modified.
At first glance, these two criteria seem inherently contradictory, but when you get more comfortable, you will see that it’s not as complicated as it seems. It tends to happen to all developers who approach solid principles for the first time, don’t worry.
The way to comply with these principles and make sure that your class is easily extensible without having to modify the code is by using abstractions.
Using inheritance or interfaces that allow polymorphic substitutions is a common way to comply with this principle. Regardless of the method used, it’s important to follow this principle to write code that is maintainable and reviewable.
3. Liskov substitution principle
Of the five solid principles, Liskov’s substitution principle is perhaps the most difficult to understand. Roughly speaking, it’s dedicated to requiring that each derived class be substitutable for its parent class.
The principle is named after Barbara Liskov, who introduced this concept of behavioral subtyping in 1987. Liskov herself explains the principle by saying:
“What is sought here is something like the following substitution property: if for every object O1 of type S there exists an object O2 of type T such that for all programs P defined in terms of T, the behavior of P does not change when O1 is replaced by O2, then S is a subtype of T.”
While this may be a difficult principle to understand at first glance, in many ways, it is simply an extension of the open-closed principle, since it’s a way to ensure that derived classes extend the base class without changing behavior.
Following this principle helps to avoid unexpected consequences of changes and avoids having to open a closed class to make changes.
It makes it easier to extend the software and, although it may slow down the development process, following this principle during development can avoid many problems during updates and extensions.
4. Interface segregation principle
The general idea of the principle of interface segregation can be summarized as it’s better to have many small interfaces than a few large ones.
Martin explains this principle by advising that developments should focus on fine-grained interfaces, for specific customer functions, without having to force the customer to use the interface.
For software engineers, this means not starting with an existing interface and adding new methods.
Instead, you have to start by building a new interface and then let the class implement various interfaces as needed.
Smaller interfaces mean that developers should prefer composition over inheritance and decoupling over coupling.
According to this principle, engineers should work toward having many customer-specific interfaces, avoiding the temptation to have one large general-purpose interface.
5. Dependency inversion principle
This principle provides a way to decouple software modules. Simply put, the dependency inversion principle means that developers should rely on abstractions, not concretions.
One popular way to comply with this principle is by using a dependency inversion pattern, although this method is not the only way to do it.
Whichever method you choose to use, finding a way to use this principle will make your code more flexible, agile, and reusable.
What are the benefits of solid principles?
So far, it’s a wonder what these 5 solid principles can bring to software development, but why don’t we look at the benefits they can generate in the bigger picture?
1. Frequency and effects of changes
The more responsibilities there are in a class, the more times you will have to change it. If multiple responsibilities are implemented, we are no longer talking about classes that are independent of each other.
It’s as simple as this: if your class changes, so do the responsibilities. But what if it has only one responsibility? You won’t have to make constant changes to the responsibility.
2. Easier to understand
Classes, software components, and microservices that have a single responsibility are much easier to explain, understand and implement than those that provide a solution for everything.
The bottom line? Fewer bugs in the speed of software development, offering easier implementation.
But hey, beware of extending simplification… If you abuse the single responsibility principle, you end up creating a class for each function, result? At the time of writing real code, you must add dependencies, making the code unworkable, confusing and unreadable.
What can we tell you as a developer? Use common sense to apply the single responsibility principle.
3. Validate the design thanks to a question
Okay, applying these principles is easier said than done. If you’re building software for the long term and need to adapt it to changing requirements, it may seem the easiest and quickest thing to do is to add a method or functionality to existing code rather than write a new class or component.
But that usually results in classes with more liability and makes it increasingly difficult to maintain the software.
You can avoid these problems by asking yourself a simple question before making any changes: What is the responsibility of your class/component/microservice?
If your answer is yes, you are most likely in breach of the single responsibility principle.
Then it’s best to take a step back and rethink your current approach. Chances are there is a better way to apply it.
Solid principles as a guide for developers
If you apply these principles in the development of any software, you will have as a result, a maintainable, scalable, testable and reusable program. If you consider the current state of the IT world, this is more suited to the market.
Sure, understanding and applying them isn’t easy, but it’s not something that with practice and dedication you can’t achieve. Moreover, it will guarantee you better results, plus it will save you time.
But do you really believe that the sound principles we’ve been talking about are viable?
Tell us your opinion in the comments, maybe you have a proposal to address some of them.