SOLID
lastmod 2026-03-16created 2021-01-2811 edits
Object-oriented design principles describe the characteristics of a design that makes good use of the features of object orientation. If design patterns are concrete solutions to problems that arise in particular situations, design principles could be called principles to follow in general situations, at a somewhat higher level. Most design patterns are built by closely following object-oriented design principles. If you design by following already proven object-oriented design principles, you can write software that is easier to maintain, more flexible, and easier to extend.
SOLID is a word formed from the first letters of the five design principles.
SRP(The Single Responsibility Princilpe) Single responsibility principle
Every object should have only one responsibility, and every service the object provides should be focused on carrying out that one responsibility. In other words, there should be only one reason to change a class.
In object-oriented programming, the single responsibility principle states that every class should have only one responsibility, and that the class should fully encapsulate that responsibility. All features provided by the class should be closely aligned with this responsibility.
OCP(The Open-Closed Principle) Open-closed principle
Software entities such as classes, modules, and functions should be open for extension but closed for modification. When a change is needed, design so that it can be made through inheritance and extension without changing existing code.
Two properties of the open-closed principle
- Open for extension.
- This means the behavior of a module can be extended. When an application's requirements change, the module can be extended by adding new behavior to fit the change. In other words, what the module does can be changed.
- Closed for modification
- The functionality of a module can be extended or changed without modifying its source code or binary code. There is no need to touch the module's executable binary form or linkable library (for example, a DLL on Windows or a .jar in Java).
LSP(The Liskov Substitution Principle) Liskov substitution principle
A child type should always be substitutable wherever its parent types are used.
It is the principle that, in a computer program, if type S is a subtype of type T, then objects of type T should be replaceable (substitutable) with objects of type S without changing any desirable properties of the program (correctness, the task performed, etc.). The Liskov substitution principle (LSP) was first introduced by Barbara Liskov in a 1987 conference keynote titled Data abstraction and hierarchy. Stated in rigorous terms, the principle is a particular case of a subtyping relation called (strong) behavioral subtyping. This definition is not merely a syntactic relation but a semantic one, because it guarantees semantic interoperability of types, which gave rise to the following principle in a 1994 paper.
Typical violation
The main article for this section is Circle ellipse problem.
A typical example of violating LSP is deriving a square class from a rectangle class that has getter and setter methods for width and height. A square class can always assume that its width and height are equal. When a square object is used in a context that deals with rectangles, it behaves unexpectedly, because the dimensions of a square cannot (or should not) be changed independently. This problem is not easy to fix. If the square class's setter methods are modified to preserve the square's invariant (i.e., width equals height), these methods undermine (violate) the postconditions of the rectangle's setters, which state that the dimensions can be changed independently. In practice, such LSP violations may or may not be a problem, depending on the postconditions or invariants actually expected by the code that uses the violating classes. The key issue here is mutability. If squares and rectangles had only getter methods (i.e., if they were immutable objects), no LSP violation would occur.
A simpler explanation
The Liskov substitution principle was presented by Barbara Liskov in 1988 to define the characteristics of a correct inheritance relationship, and it means that a subtype should always be substitutable for its base type.
Being substitutable means that a child class must be guaranteed to perform at least the behaviors possible in its parent class.
That is, it means that when an instance of a child class is used in place of an instance of the parent class, the code should work as originally intended.
This is described as behavior being consistent between the parent class and the child class.
ISP(The Interface Segregation Principle) Interface segregation principle
Don't form dependencies on methods you don't use. Give the users of an object an interface with only the methods those users need.
The interface segregation principle states that clients should not depend on methods they do not use. By splitting large interfaces into specific, smaller units, the interface segregation principle lets clients use only the methods they actually need. Such smaller units are also called role interfaces. The interface segregation principle weakens the internal dependencies of a system, making refactoring, modification, and redeployment easier. The interface segregation principle is one of the five SOLID principles and is similar to GRASP's high cohesion principle.
DIP(The Dependency Inversion Principle) Dependency inversion principle
High-level modules should not depend on low-level modules. Abstractions should not depend on concrete things. Design both high-level and low-level modules to depend on abstractions as much as possible, and don't design them to depend on concrete classes.
Following this principle, by reversing (inverting) the traditional dependency relationship in which the upper layer (policy decisions) depends on the lower layer (details), the upper layer can be made independent of the lower layer's implementation.
This principle states the following.
- High-level modules should not depend on low-level modules. Both high-level and low-level modules should depend on abstractions.
- Abstractions should not depend on details. Details should depend on abstractions.
This principle provides the overarching principle of object-oriented design: 'both high-level and low-level objects should depend on the same abstraction'.
See also
- Object-oriented programming (Object Oriented Programming)
- Clean Code
- CRISP
- Single source of truth (Korean: 단일 진실 공급원)
Favorite site
- The 5 principles of object-oriented development: SOLID
- Understanding the SOLID object-oriented design principles through Figma
- The 5 principles of object orientation
- [Recommended] Namuwiki - Object-oriented programming/Principles