In this article, we will discuss what is SOLID principles, why we should intend them. Also, we will take a look at examples of "S" principle using Javascript.
What are principles?
In simple words, principles are a set of rules, restrictions, set actions. Such rules help us, developers to keep our code more readable, maintainable.
Also if we know such principles, as SOLID, DRY, KISS, GoF patterns we can talk with other developers using the same language. You can use specific world from principles and say, something like "you made a little bit of a mistake, please, use the first SOLID principle."
Or, for example, when one developer from a team discusses a new feature with other: "Hey, Tom. We are going to add a new library for the new DB, that will take new data for our application, but unfortunately, this library has incompatible interfaces with our current code implementation."
"Please, create a new class, and let’s use an adapter pattern. This will help us keep working with all previous code and use new features from the new DB."
So, instead of discussing many aspects of implementation, when one developer says: "please use an adapter", and another developer, of course, if he knows this principle, understands what he should do.Another example is if you join a new project and that project uses MVC pattern and you know MVC, it will be much easy to understand a new project, how it works, where you can find DB logic, where you can find view logic. It helps to reduce the time to understand the project, so you can start to make tasks faster.
What is SOLID?
SOLID is an acronym for the first five object-oriented design principles by Robert C. Martin.The purpose of these principles is: to make your code, architecture more readable, maintainable, flexible.
S - Single-Responsibility Principle. One entity should solve one specific task. When I wrote entity, I mean that it could be one class, one component, one service, one file.
Why we should use this principle?
Let’s imagine that we are writing our code, without this principle. What we will have later?Our class (function, component, service) knows about everything and we will have a lot of related code. If something breaks in one place, it will affect other places, which in theory could not depend on each other.Maintaining this class (function, component, service) is really hard. Especially for that developer, who has never worked with this class before. During adding new methods there, you can break something, or you can face unpredictable behavior.It can be hard to read this code. If you have a file with 1000, 2000, 5000 thousand code lines it can be really painful to understand this file. So, let’s take a look at an example, that has been written without a single responsibility principle.
As you can see we have a really simple class, that represents a movie. We can see some initial setup in the constructor and some additional methods, that give the ability to change description, rating, saving the movie to DB and to file system.From the first point of view it seems that everything is ok with this class, but let’s think about the problem, which could be later:
- In the future, we can decide to add new methods for this class, for example getting a movie from DB, validating movie before saving, making some transformation, rendering movie on the page, deleting movie from DB, deleting the movie from a file, edit movie in DB, in the file, on the page, etc. Our class will be “God object”, antipattern.
- In the future when you decide to change one method, there is a big chance that something will break in another place.
- Code duplication. Let’s imagine, that we have another class, like Audio, or Picture. And these classes also need to contain such logic as working with DB (create, read, update, delete), the same with the filesystem, the same with validation. What we will do in such a case? The first that can appear in our mind is to make the same methods in each class (Audio, Picture, Movie). If we do this, what will happen? The first antipattern we already have: “God object” Now, we can see the second antipattern “DRY” (Don’t repeat yourself).
If for some reason, we want to change our DB logic, for example, add the ability to save to file not in simple text format, but for example, like XML or JSON, we should go through all methods, at all classes and make changes. If our system contains a lot of classes, and each of them has its own method, we sure can forget to change this logic somewhere. It’s a problem.
- The next problem we make our system really hard to understand and maintain. Let’s imagine when a newcomer tries to change some logic, he should find the correct place where he needs to make changes, but from the 3d bullet, we know that there are many places where he should make changes, that’s why he will make mistakes that are in the future can create many unpredictable problems.
We could continue this list of problems, but I hope you now understand the main problems.How can we rewrite our logic? First of all, we should remember: “Single responsibility” really says “one entity should solve one specific task”.So, what tasks are in our Movie class?
Knowing this, we can create 3 classes: Movie, DB, FileSystem.
Now we have 3 separate classes, that make only one specific task.
- Movie works only with movie information
- DB works only with DB manipulation
- FileSystem works only with file manipulation
This separation gives us many benefits:
- DRY principle. Now, we don’t need to duplicate our logic working with DB (files). We can pass any entities (Audio, Picture) into this class, and this class will save them to DB.
- In practice it will be a little bit different approach than this now, for example, we can use MVC, where for each entity we create service, and service uses our common DB class or Filesystem class, but the purpose of “Single responsibility” doesn’t change.
- Our code is really cleaner and simpler. Now, we know, if we should change our logic for working with DB, we have only one place, it’s DB class. If we face a bug during saving something to DB, we also know that it’s DB class. When a newcomer needs to change something, we can say to him, pls, open DB class, and there you can see all the needed information.
- Now, we don’t have “God object”
That's all for today. In the next article, we will take a look at the second "O" principle.