当前位置:网站首页>Solid principle: explanation and examples
Solid principle: explanation and examples
2022-07-02 08:30:00 【J-A】
In object oriented programming ,SOLID yes 5 Abbreviation for an important design principle . First, by the famous software Masters Robert C.Martin (Bob uncle ) stay Design Principles and Design Patterns It is proposed that , later Michael Feathers use SOLID To summarize these five principles .
SOLID Principles make software design Easier to understand 、 Flexible and maintainable . As a software engineer , this 5 There are three principles we must know .
this paper , I will cover these principles , And illustrate with examples how it violates the principle , And how to correct it to meet SOLID principle .
S — Single responsibility principle
In programming , The single responsibility principle means that each module or class should have only one responsibility .
You may have heard such a proverb “ Do a thing and do it well ”, This refers to the principle of single responsibility .

In the article 《Principles of Object Oriented Design》 in ,Bob Uncle defines responsibility as “ The reason for the change ”. And think that there is one and only one reason to change the class or module .
class User
{
void CreatePost(Database db, string postMessage)
{
try
{
db.Add(postMessage);
}
catch (Exception ex)
{
db.LogError("An error occured: ", ex.ToString());
File.WriteAllText("\LocalErrors.txt", ex.ToString());
}
}
}
In the above code example , We noticed that *CreatePost()* Methods have multiple functions , Create a new message , Record the error log in the database and in the local file .
This violates the principle of single responsibility . We try to modify it as follows :
class Post
{
private ErrorLogger errorLogger = new ErrorLogger();
void CreatePost(Database db, string postMessage)
{
try
{
db.Add(postMessage);
}
catch (Exception ex)
{
errorLogger.log(ex.ToString())
}
}
}
class ErrorLogger
{
void log(string error)
{
db.LogError("An error occured: ", error);
File.WriteAllText("\LocalErrors.txt", error);
}
}
By abstracting the error log function , We no longer violate the principle of single responsibility .
Now there is 2 Classes , Each class has a responsibility ; Create mail and record an error log .
O — Open/closed principle
In programming , The open close principle refers to the software object ( class , modular , Function, etc. ) It should be open to extension , Turn off for changes .

If you are familiar with OOP, Then polymorphism should be no stranger . Implement through inheritance or interface , Make an abstract class have multiple subclasses , You can ensure that the code conforms to the opening and closing principle .
This sounds a little confused , So let's take an example , You'll know exactly what I'm talking about .
class Post
{
void CreatePost(Database db, string postMessage)
{
if (postMessage.StartsWith("#"))
{
db.AddAsTag(postMessage);
}
else
{
db.Add(postMessage);
}
}
}
In this code snippet , Whenever a message is written in characters “#“ start , We all need to make some assignments . However , When there are different characters beginning , Code will behave differently , This goes against the principle of opening and closing .
such as , If we want to use “@” start , We have to CreatePost() Add a ‘else if’, This modifies the class .
Inheritance is simply used here to make the code conform to the open and close principle .
class Post
{
void CreatePost(Database db, string postMessage)
{
db.Add(postMessage);
}
}
class TagPost : Post
{
override void CreatePost(Database db, string postMessage)
{
db.AddAsTag(postMessage);
}
}
By using inheritance , rewrite *CreatePost()* Method to create the extended behavior of the message .
Now? , Judge the first character “#” It can be handled elsewhere in the software . The cooler thing is , If we want to change postMessage The way to judge , Can not affect the behavior of the base class .
L — Liskov substitution principle
This principle is probably the most difficult to understand at the first introduction .

In programming , The Richter substitution principle refers to if S yes T Subclasses of , that T Examples of can be used S Instead of .
A more general expression is , Without changing the correctness of the program , A derived class object can replace its base class object in a program .
class Post
{
void CreatePost(Database db, string postMessage)
{
db.Add(postMessage);
}
}
class TagPost : Post
{
override void CreatePost(Database db, string postMessage)
{
db.AddAsTag(postMessage);
}
}
class MentionPost : Post
{
void CreateMentionPost(Database db, string postMessage)
{
string user = postMessage.parseUser();
db.NotifyUser(user);
db.OverrideExistingMention(user, postMessage);
base.CreatePost(db, postMessage);
}
}
class PostHandler
{
private database = new Database();
void HandleNewPosts() {
List<string> newPosts = database.getUnhandledPostsMessages();
foreach (string postMessage in newPosts)
{
Post post;
if (postMessage.StartsWith("#"))
{
post = new TagPost();
}
else if (postMessage.StartsWith("@"))
{
post = new MentionPost();
}
else {
post = new Post();
}
post.CreatePost(database, postMessage);
}
}
}
Because there is no override ,CreatePost() Method in subclass MentionPost Will not play its due role .
Revised as follows :
...
class MentionPost : Post
{
override void CreatePost(Database db, string postMessage)
{
string user = postMessage.parseUser();
NotifyUser(user);
OverrideExistingMention(user, postMessage)
base.CreatePost(db, postMessage);
}
private void NotifyUser(string user)
{
db.NotifyUser(user);
}
private void OverrideExistingMention(string user, string postMessage)
{
db.OverrideExistingMention(user, postMessage);
}
}
...
By refactoring MentionPost class , Can meet the replaceability .
This is just a simple example that does not violate the Richter substitution principle . However , In actual use , This situation can be achieved in many ways and is not easy to identify .
I — Interface segregation principle
This principle is easy to understand , actually , If you are used to using interfaces , There is a high probability that this principle will be used .

In programming , The principle of interface isolation means that customers should not be forced to use methods or functions that are useless to them .
simply , Don't add new methods to existing interfaces to realize new functions . Contrary , You can create new interfaces , If necessary , You can make your class implement multiple interfaces .
interface IPost
{
void CreatePost();
}
interface IPostNew
{
void CreatePost();
void ReadPost();
}
In the above code example , Suppose I already have one IPost Interface , contain CreatePost() Method ; later , I added a new method ReadPost(), This interface has been modified , become IPostNew Interface , This violates the principle of interface isolation . Revised as follows :
interface IPostCreate
{
void CreatePost();
}
interface IPostRead
{
void ReadPost();
}
Once any class needs to implement this 2 A way , This will be achieved at the same time 2 Interface .
D - Dependency inversion principle
Last , Let's take a look D, The last design principle .

In programming , The dependency inversion principle is used to decouple modules in software . This principle is expressed as follows :
- High level modules should not rely on low-level modules , Instead, we should rely on abstraction ;
- Abstraction should not rely on implementation details , Implementation details should rely on abstraction .
In order to follow this principle , We need to use a design pattern called Dependency injection , Typical , Dependency injection takes the constructor of the class as the input parameter .
class Post
{
private ErrorLogger errorLogger = new ErrorLogger();
void CreatePost(Database db, string postMessage)
{
try
{
db.Add(postMessage);
}
catch (Exception ex)
{
errorLogger.log(ex.ToString())
}
}
}
Observe that we are Post Class ErrorLogger example , If we want to use different logs , We need to change Post class , This goes against the principle of dependence inversion . Revised as follows :
class Post
{
private Logger _logger;
public Post(Logger injectedLogger)
{
_logger = injectedLogger;
}
void CreatePost(Database db, string postMessage)
{
try
{
db.Add(postMessage);
}
catch (Exception ex)
{
_logger.log(ex.ToString());
}
}
}
By using dependency injection , We no longer rely on Post Class to define the log of the specified type .
OK, After introducing so many , I have also roughly understood these principles . These principles are different , At the same time, they are also connected .

- The principle of single responsibility is SOLID The basis of all principles and ideas for solving problems .
- The principle of opening and closing is the principle that directly guarantees the quality of code , To solve the vulnerability of design 、 Ossification 、 Difficult to read 、 Difficult to reuse , The key to applying the opening and closing principle is how “ abstract ”.
- The Richter substitution principle ensures that subclasses and superclasses are “is a” The relationship between , To help realize the opening and closing principle . The principle is in use , Extend the object-oriented perspective “is a” It's about behavior , And the correctness of the model is not inherent , It is embodied by its client program .
- The interface isolation principle provides a solution , Without violating the Richter replacement principle , How to realize the open close principle . At the same time, the idea of interface isolation also embodies the principle of single responsibility .
- Dependency inversion principle is the watershed between procedural design and object-oriented design , Through appropriate abstraction , Make high-level modules as reusable and testable as low-level modules . It's also used to guide interface isolation principles .
Reference resources
【2】Single Responsibility Principle in C++
【4】Open Closed Principle in C++
【5】 Opening and closing principle
【6】Liskov’s Substitution Principle in C++
【7】 Richter's principle of substitution
【8】Interface Segregation Principle in C++
【9】 Interface isolation principle
【10】Dependency Inversion Principle in C++
【11】 The principle of Dependence Inversion
That’s it!If you have any questions or feedback, please feel free to comment below.
-EOF-
边栏推荐
- Opencv3 6.3 reduced pixel sampling with filters
- k8s入门:Helm 构建 MySQL
- Chinese garbled code under vscade
- VS Code配置问题
- Global and Chinese market of snow sweepers 2022-2028: Research Report on technology, participants, trends, market size and share
- HCIA - data link layer
- Introduction to parameters of CarSim pavement 3D shape file
- Hcia - Application Layer
- Implementation of bidirectional linked list (simple difference, connection and implementation between bidirectional linked list and unidirectional linked list)
- Web安全--核心防御机制
猜你喜欢

Sqlyog remote connection to MySQL database under centos7 system

Use the kaggle training model and download your own training model

Generate database documents with one click, which can be called swagger in the database industry

Comparable,Comparator,Clonable 接口使用剖析

ICMP协议

c语言将字符串中的空格替换成%20

Use of opencv3 6.2 low pass filter

How to back up the configuration before the idea when reinstalling the idea

路由基础—动态路由

Fundamentals of music theory (brief introduction)
随机推荐
Global and Chinese market of wire loop, 2022-2028: Research Report on technology, participants, trends, market size and share
Linked list classic interview questions (reverse the linked list, middle node, penultimate node, merge and split the linked list, and delete duplicate nodes)
Intelligent manufacturing solutions digital twin smart factory
Library function of C language
CarSim problem failed to start solver: path_ ID_ OBJ(X) was set to Y; no corresponding value of XXXXX?
顺序表基本功能函数的实现
CarSim learning experience - rough translation 1
Carla-UE4Editor导入RoadRunner地图文件(保姆级教程)
The best blog to explain the basics of compilation (share)
双向链表的实现(双向链表与单向链表的简单区别联系和实现)
Summary of one question per day: linked list (continuously updated)
TCP/IP—传输层
Media query usage
Opencv common method source link (continuous update)
力扣方法总结:双指针
Principes fondamentaux de la théorie musicale (brève introduction)
Opencv3 6.3 reduced pixel sampling with filters
[dynamic planning] p4170: coloring (interval DP)
Development of digital collection trading website development of metauniverse digital collection
Makefile基本原理