Blog

SOLID – Clean and maintainable software design platform

Solid

SOLID These are the five design principles in object-oriented programming (OOP), proposed by Robert C. Martin (Uncle Bob) and Michael Feathers. These are the core principles that help programmers write code that is easy to understand, easy to maintain, and easy to expand – these are very important factors in real-world software projects.

While fully applying all five principles in every situation is not easy, understanding and adhering to them at a reasonable level will significantly improve the quality of your code and software architecture.

SOLID stands for the following five principles:

  1. S – Single Responsibility Principle (SRP)
    Each class should only be responsible for a single responsibility.
  2. O – Open/Closed Principle (OCP)
    Class should Open for expansion, but Close to edit.
  3. L – Liskov Substitution Principle (LSP)
    A subclass can replace parent class without altering the correctness of the program.
  4. I – Interface Segregation Principle (ISP)
    Avoid forcing clients to depend on interfaces. that they do not use.
  5. D – Dependency Inversion Principle (DIP)
    Depends on abstractions, independent of implementations.


Single responsibility principle

"A class should have only one reason to change."

The first principle in SOLID corresponds to the letter S – is Single Responsibility Principle. This principle emphasizes that Each class should only be responsible for a single responsibility.In other words, a class should only focus on handling a specific aspect of the system.

Violating this principle often occurs when a class "takes on" too many functions, from business logic processing, data manipulation, to report generation... This makes the class become bulky, hard to read, hard to control, and especially hard to maintain or expand in the future.

In the software development industry, Changes in requirements are inevitable.. If code is written unclearly, each modification is likely to cause chain errors, wasting time and effort. Therefore, it is essential to Write single-responsibility code is one of the most effective ways to keep a system clean and easy to maintain.


Solid Example


Open/Closed principle

"Open for extension, closed for modification."

The second principle in SOLID – corresponding to the letter O – is Open/Closed Principle, stated by Bertrand Meyer. This principle encourages that Classes, modules, or functions should allow for extension (open for extension) but should not allow changes to the original source code (closed for modification)..

In other words, when there is a requirement to change the behavior of the system, you Extend functionality through inheritance, composition, or using interfaces., instead of directly modifying the existing class. This helps Avoid breaking existing stable logic and minimize errors when modifying tested code.


Why is this principle important?

In practice, software requirements are constantly changing—adding new features, modifying business rules, and so on. If you have to modify existing classes every time a change is made, the risk of introducing errors is very high. Adhering to the OCP principle helps your system:

  • Easy maintenance and scalability
  • Reduce risk of error propagation
  • Enhance your ability to Code reuse


Liskov Substitution Principle (LSP)

"A child class can replace a parent class without changing the correctness of the program."

The third principle in SOLID – corresponding to the letter L – is Liskov Substitution Principle, stated by Barbara Liskov in 1987. The content of this principle is:

"If S is a subtype of T, then objects of T can be replaced by objects of S without changing the correctness of the program."

In simpler terms: A child class must be able to be used in place of the parent class in a fully compatible manner., without breaking the program's logic. If the child class Overriding methods, change behavior, or Functional limitations causes the program to not function as expected, then that class Violated the LSP principle.


LSP ensures that you can inheritance without breaking system. If you use inheritance to extend functionality but change the behavior or contract defined in the parent class, you will create errors that are difficult to control in the program.


In summary:

  • Subclass Keep the interface consistent. and the behavior of the parent class.
  • Using child classes instead of parent classes Do not introduce errors or unintended behavior..
  • If you cannot comply, composition may be an alternative solution to inheritance.


Interface segregation principle

"Clients should not be forced to depend on interfaces they do not use."

The fourth principle in SOLID – corresponding to the letter I – is Interface Segregation Principle, also known as Principle of interface separation. This principle suggests that:

Instead of creating a large interface, it is better to divide it into smaller interfaces, each containing methods related to a specific group of functions.

Why is it necessary to separate the interface?

A large interface (also known as a "fat interface") forces implementing classes to being forced to implement methods that are not needed. This makes the code complex, difficult to maintain, and violates the principles. single responsibility and create unnecessary dependencies.

Conversely, breaking down the interface helps:

  • A class only needs to implement its specific responsibilities.
  • Increase modularity and reusability
  • Reduce dependencies between components in the system


In summary:

  • Each interface should serve a specific group of objects.
  • Clients should only depend on what they actually use..
  • ISP is particularly important in languages with clear interfaces such as TypeScript, Java, C#, etc.


D – Dependency Inversion Principle (DIP)

"Depend on abstraction, not on details."

Fifth principle – corresponding to the letter D In SOLID – is Dependency Inversion Principle. This principle is stated with two important propositions:

  1. High-level modules should not depend on low-level modules. Both should depend on abstraction.
  2. Abstraction should not depend on details. Details should depend on abstraction.


Typically, code is prone to errors when high-level classes (containing business logic) directly depends on Low-level classes (handling details such as file reading, database connections, APIs, etc.). This makes the system rigid, difficult to scale and difficult to test.

DIP encourages us to reverse dependencies: high-level and low-level classes should all depend on an interface or abstract class, thereby separating business logic from implementation details. This makes the system flexible, easy to change, and easy to test (dependencies can be mocked).


In summary:

  • Instead of directly creating dependent objects within a class (using new), pass them from outside (typically through dependency injection).
  • Designing code that is oriented toward interface or abstract class to increase abstraction and flexibility.
  • DIP helps the system scalable, maintainable, and testable


Conclusion

The above is an overview of The 5 SOLID principles – the core foundations of object-oriented software design. Understanding and applying these principles correctly will help you write code that is readable, scalable, and maintainable, and minimizing errors as the software evolves over time.

We hope this article will be of some assistance to you in your studies and work, especially when building high-quality and sustainable software systems.

Share this post

Ready to Launch your vision?

Build Your High-Performance projects with vietswiss

Let us transform your ideas into a digital reality that captivates your audience and delivers tangible success.