To become a senior among millions of programmers!
During the course of the study, most of the students learned some basic OOP concepts as follows:
- Abstraction
- Encapsulation
- Inheritance
- Polymorphism
These concepts have been taught quite clearly, and almost every interview has questions about this concept. Because these 4 concepts are quite basic, you can not google it yet to learn more.
The principles that I introduce today are those in OOP design. These are the principles gathered by countless developers, drawn from thousands of successful and failed projects. A project that applies these principles will have easier to read, test, and clearer code. And the most important thing is that the maintenance code will be a lot easier. . Mastering these principles and applying them in the design + coding will help you go one step further on the path to a senior.
SOLID means “hard,” more apply; you will code “hard.” Just kidding, it is a set of the following 5 principles:
- Single responsibility principle
- Open / closed principle
- Liskov substitution principle
- Interface segregation principle
- Dependency inversion principle
In this article's content, I give a general introduction so that you have an overview of these principles. For detailed articles, click on the link on each principle.
1. Single responsibility principle
The first principle corresponds to the letter S in SOLID. Principle content:
A class should hold only 1 Responsibility
(Class can be modified for only 1 reason)
To understand this principle, let’s take an example with a class that violates the principle. We have 1 class as follows:
public class ReportManager()
{
public void ReadDataFromDB();
public void ProcessData();
public void PrintReport();
}
This class holds up to three responsibilities: Reading data from the DB, processing data, printing the results. Therefore, as long as we change the DB, change the way the results are output, … we will have to modify this class. Later, the class will swell. According to the principle, we must separate this class into 3 separate classes. While the number of classes is higher than the fixes will be simpler, the shorter class should also have fewer bugs.
2. Open/closed principle
The second principle corresponding to the letter O in SOLID. Principle content:
open for extension but closed for modification.
According to this principle, every time we want to add functionality.. to the program, we should write a new class that extends the old class (by inheriting or owning the old class), so we shouldn’t modify the old class.
3. Liskov Substitution Principle
The third principle corresponding to the letter L in SOLID. Principle content:
In a program, objects of a subclass can replace the parent class without changing the correctness of the program
Somewhat confusing? No problem, when I first read it too. Imagine you have a parent class named Duck. The classes DabblingDuck, Eider can inherit this class, the program runs normally. However, if we write the class ElectricDuck, the battery needs to be run. When this class inherits Duck class, because no battery cannot run, it will cause an error. It is a violation of this principle.
4. Interface Segregation Principle
The fourth principle corresponding to the letter I in SOLID. Principle content:
Instead of using a large interface, we should split it into many small interfaces, with many specific purposes
This principle is quite easy to understand. Imagine we have 1 large interface, about 100 methods. The implements will be quite difficult; besides, it can be redundant because a class does not need to use all 100 methods. When separating the interface into many small interfaces, including related methods, the implementation and management will be easier.
5. Dependency inversion principle
The last principle corresponding to the letter D in SOLID. Principle content:
- High-level modules should not depend on low-level modules.
Both should depend on the abstraction. - Interface (abstraction) should not depend on details, but vice versa.
(The classes communicate with each other through interfaces,
not through the implementation.)
This principle is quite clever; I will take a practical example. We all know 2 types of lamps: round lamps and fluorescent lamps. They all have round tails to replace round lights with fluorescent lights for each other easily.
Here, the main interface is the round tail, and the implementation is round and fluorescent bulbs. We can easily swap between the 2 types of balls because the power socket only cares about the interface (round tail), not the implementation.
In code too, when applying Dependency Inverse, we only need to care about the interface. To connect to the database, we need to call the Get, Save … function of Interface IDataAccess. When replacing the database, we need to change the implementation of this interface.
I talk about this principle quite carefully because it is quite important. I also have a series about Dependency; you could find it on my page.