news 2026/9/21 12:39:30

SOLID软件设计原则 解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SOLID软件设计原则 解析

前言:在平时coding过程中,大部分程序员可能把更多精力和时间花在功能的实现和完成上面,对于代码的可读性、可读性及可扩展性没有过多的关注,这可能会造成后期功能扩展困难、新人无法理解等问题。这里介绍一些软件代码设计原则,帮助大家提升代码质量。

目录

一、SOLID软件设计原则

二、单一职责原则(Single Responsible Principle)

二、开闭原则(Open Close Principle)

三、里氏替换原则(Liskov Substitution Principle)

四、接口隔离原则(Interface Segregation Principle)

五、依赖倒置原则(Dependency Inversion Principle)


一、SOLID软件设计原则

SOLID是面向对象软件设计中5个基础设计原则的简写,由Robert C. Martin提出,是设计模式的指导思想。这些原则包括单一职责原则、开闭原则、里氏替换原则、接口隔离原则、依赖倒置原则。下面章节分别展开介绍。

二、单一职责原则(Single Responsible Principle)

1)定义:一个类应当只做一件事情,只有一个引起它变化的原因

2)思想:避免一个类同时负责多个功能,否则对一个功能的修改可能会影响到其他功能,修改扩展成本增加。

3)示例

反例:一个UserManager类同时负责用户信息管理用户日志记录,如果日志的存储方式修改(比如从本地文件改成数据库),就需要修改这个类,违反了单一职责。

正例:拆分为两个类:

// 只负责用户信息的管理 class UserManager { public: void addUser(const std::string& username) { // 处理用户添加的逻辑 } void deleteUser(const std::string& username) { // 处理用户删除的逻辑 } }; // 只负责用户相关的日志记录 class UserLogger { public: void logUserOperation(const std::string& username, const std::string& operation) { // 处理日志记录的逻辑 } };

二、开闭原则(Open Close Principle)

1)定义:软件模块(类、函数等)应该对扩展开放,对修改关闭。

2)思想:当需要新增功能时,应当通过扩展已有代码模块来实现,而不是在已有代码上直接修改、打补丁,防止补丁上打补丁,时间长了就难以维护了。

3)示例

反例:一个ShapeCalculator类,计算不同图形的面积,如果新增一种图形(比如椭圆),就需要修改类的代码:

// 反例:新增图形需要修改这个类 class ShapeCalculator { public: double calculateArea(const std::string& shapeType, double param1, double param2) { if (shapeType == "circle") { return M_PI * param1 * param1; } else if (shapeType == "rectangle") { return param1 * param2; } // 新增椭圆需要在这里加else if return 0; } };

正例:通过抽象类+继承实现

// 抽象的图形类 class Shape { public: virtual double calculateArea() const = 0; virtual ~Shape() = default; }; // 圆形类,继承Shape class Circle : public Shape { private: double radius; public: Circle(double r) : radius(r) {} double calculateArea() const override { return M_PI * radius * radius; } }; // 矩形类,继承Shape class Rectangle : public Shape { private: double width; double height; }; // 面积计算器,只依赖抽象类,新增图形不需要修改这个类 class ShapeCalculator { public: double calculateArea(const Shape& shape) { return shape.calculateArea(); } };

上述代码中出现了虚函数和抽象类的概念,如需要可参考之前的文章:C++ 虚函数 解析指南-CSDN博客

三、里氏替换原则(Liskov Substitution Principle)

1)定义:子类对象可以替换父类对象在程序中的所有使用场景,且不会改变程序的正确性。

2)思想:子类必须完全实现父类功能,不能破坏父类的行为,避免继承关系的滥用。

3)示例

反例:正方形继承矩形,但是正方形的宽和高必须相等,修改宽的时候高也会变化,破坏了矩形的行为

class Rectangle { protected: double width; double height; public: void setWidth(double w) { width = w; } void setHeight(double h) { height = h; } double getArea() { return width * height; } }; // 反例:正方形继承矩形,但是setWidth和setHeight的行为不符合父类的约定 class Square : public Rectangle { public: void setWidth(double w) override { width = w; height = w; } void setHeight(double h) override { width = h; height = h; } };

正例:重新设计继承关系,使得正方形与矩形都继承抽象的Shape类。

四、接口隔离原则(Interface Segregation Principle)

1)定义:客户端不应当依赖它不需要的接口,一个类对另一个类的依赖应当建立在最小接口上。

2)思想:避免设计大而全的接口,接口应当拆分多个小的,高内聚、低耦合。

3)示例

反例:一个大的Worker接口,包含了所有工作相关的方法,但是不同的 worker 只需要其中一部分

// 反例:大而全的接口 class Worker { public: virtual void work() = 0; virtual void eat() = 0; virtual void sleep() = 0; }; // 机器人只需要work,但是必须实现eat和sleep class Robot : public Worker { public: void work() override { /* 工作逻辑 */ } void eat() override { /* 机器人不需要吃饭,空实现 */ } void sleep() override { /* 机器人不需要睡觉,空实现 */ } };

正例:拆分为小接口

// 只包含工作的接口 class Workable { public: virtual void work() = 0; virtual ~Workable() = default; }; // 只包含休息相关的接口 class Restable { public: virtual void eat() = 0; virtual void sleep() = 0; virtual ~Restable() = default; }; // 机器人只实现Workable接口 class Robot : public Workable { public: void work() override { /* 工作逻辑 */ } }; // 人类实现Workable和Restable接口 class HumanWorker : public Workable, public Restable { public: void work() override { /* 工作逻辑 */ } void eat() override { /* 吃饭逻辑 */ } void sleep() override { /* 睡觉逻辑 */ } };

五、依赖倒置原则(Dependency Inversion Principle)

1)定义:上层模块不应当依赖底层模块抽象不应当依赖细节,细节应当依赖抽象。

2)思想:通过抽象(抽象类或接口)实现上层与底层解耦,使得模块之间依赖关系倒置,提高灵活性。

3)示例

反例:上层模块ReportGenerator直接依赖底层模块MySQLDatabase,如果需要切换数据库(比如改成PostgreSQL),就需要修改ReportGenerator

// 反例:上层依赖底层的具体实现 class MySQLDatabase { public: std::string getData() { return "从MySQL获取的数据"; } }; class ReportGenerator { private: MySQLDatabase db; public: std::string generateReport() { return "报告内容:" + db.getData(); } };

正例:通过抽象接口解耦

// 抽象的数据库接口 class Database { public: virtual std::string getData() const = 0; virtual ~Database() = default; }; // MySQL的具体实现,依赖抽象接口 class MySQLDatabase : public Database { public: std::string getData() const override { return "从MySQL获取的数据"; } }; // PostgreSQL的具体实现,依赖抽象接口 class PostgreSQLDatabase : public Database { public: std::string getData() const override { return "从PostgreSQL获取的数据"; } }; // 高层模块依赖抽象接口,而不是具体实现 class ReportGenerator { private: const Database& db; public: // 通过构造函数注入依赖 ReportGenerator(const Database& database) : db(database) {} std::string generateReport() { return "报告内容:" + db.getData(); } };

结束语:一般这5种原则不会孤立存在,通常两三个会结合在一起使用。读者可参考进行理解消化,最终目的是应用于实际项目中,实现代码质量显著提升。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/22 5:09:17

MaxScript 实现多边形层级切换按钮

大家好!欢迎来到这个 MaxScript 编程教程。今天我们将学习如何创建一个实用的 3ds Max 工具——一个智能的层级切换按钮。这个工具的核心功能是通过一个 checkbutton(复选框按钮)实现可编辑多边形对象的多边形子层级与对象层级的快速切换。 在三维建模工作中,频繁地在不同…

作者头像 李华
网站建设 2026/9/22 0:38:00

NideShop电商系统:打造高效在线商城的终极Node.js解决方案

在数字化经济时代,企业面临着如何快速搭建功能完善、性能稳定的在线商城的挑战。传统电商平台开发周期长、成本高、定制性差,让许多中小企业望而却步。NideShop电商系统正是为解决这一痛点而生,为开发者提供了一个基于Node.js的完整电商解决方…

作者头像 李华
网站建设 2026/9/21 15:00:11

Selenium 自动化 | 案例实战篇

Chrome DevTools 简介 Chrome DevTools 是一组直接内置在基于 Chromium 的浏览器(如 Chrome、Opera 和 Microsoft Edge)中的工具,用于帮助开发人员调试和研究网站。 借助 Chrome DevTools,开发人员可以更深入地访问网站&#xf…

作者头像 李华
网站建设 2026/9/21 5:02:01

开源RAW图像处理工具darktable:5大核心模块构建专业摄影工作流

作为摄影师,你是否面临RAW格式照片处理的挑战?商业软件的订阅费用、复杂的操作界面让专业图像处理变得遥不可及。darktable作为一款开源免费的RAW图像处理工具,为你提供完整的摄影工作流解决方案,从照片管理到专业调色&#xff0c…

作者头像 李华
网站建设 2026/9/22 4:16:32

Wan2.1-I2V-14B-480P:如何在消费级GPU上实现实时图像到视频生成

Wan2.1-I2V-14B-480P:如何在消费级GPU上实现实时图像到视频生成 【免费下载链接】Wan2.1-I2V-14B-480P-StepDistill-CfgDistill-Lightx2v 项目地址: https://ai.gitcode.com/hf_mirrors/lightx2v/Wan2.1-I2V-14B-480P-StepDistill-CfgDistill-Lightx2v Wan2…

作者头像 李华
网站建设 2026/9/21 23:10:10

百度贴吧终极体验优化:baidu-tieba-userscript完整使用指南

你是否厌倦了百度贴吧繁琐的操作和无处不在的推广内容?是否希望拥有更高效、更智能的贴吧使用体验?今天,我将为你介绍一个强大的开源工具——baidu-tieba-userscript,它能够彻底改变你在贴吧的日常使用体验。 【免费下载链接】bai…

作者头像 李华