C++中的八大设计原则

目录

摘要

C+中的8大设计原则

1. 单一职责原则 (Single Responsibility Principle, SRP)

2. 开放封闭原则 (Open/Closed Principle, OCP)

3. 里氏替换原则 (Liskov Substitution Principle, LSP)

4. 依赖倒置原则 (Dependency Inversion Principle, DIP)

5. 接口隔离原则 (Interface Segregation Principle, ISP)

6. 迪米特法则 (Law of Demeter, LoD)

7. 合成复用原则 (Composite Reuse Principle, CRP)

8. 最少知识原则 (Least Knowledge Principle, LKP)

C++中的23种设计模式


摘要

C++ 中的八大设计原则可以帮助我们创建高内聚、低耦合的代码。

C+中的8大设计原则

1. 单一职责原则 (Single Responsibility Principle, SRP)

- 一个类应该只有一个引起变化的原因,即一个类只负责一个职责。可以提高类的可读性和可维护性,降低类的复杂度,但可能导致类的数量增加,进而增加系统设计的复杂性。

class UserManager {
public:void createUser(std::string username, std::string password) {// 创建用户}void deleteUser(std::string username) {// 删除用户}void generateUserReport(std::string username) {// 生成用户报告}void sendNotification(std::string message) {// 发送通知}
};// 应用SRP后
class UserCreator {
public:void createUser(std::string username, std::string password) {// 创建用户}
};class UserDeleter {
public:void deleteUser(std::string username) {// 删除用户}
};class UserReporter {
public:void generateUserReport(std::string username) {// 生成用户报告}
};class NotificationSender {
public:void sendNotification(std::string message) {// 发送通知}
};

2. 开放封闭原则 (Open/Closed Principle, OCP)

- 软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。可以提高系统的可扩展性,减少修改代码引入错误的风险,但需要仔细设计抽象层次,可能增加系统的复杂度。

class PaymentProcessor {
public:void processPayment(std::string paymentType) {if (paymentType == "CreditCard") {// 处理信用卡支付} else if (paymentType == "PayPal") {// 处理PayPal支付}}
};// 应用OCP后
class IPayment {
public:virtual void processPayment() = 0;
};class CreditCardPayment : public IPayment {
public:void processPayment() override {// 处理信用卡支付}
};class PayPalPayment : public IPayment {
public:void processPayment() override {// 处理PayPal支付}
};class PaymentProcessor {
public:void processPayment(IPayment* payment) {payment->processPayment();}
};

3. 里氏替换原则 (Liskov Substitution Principle, LSP)

- 子类对象应该能够替换掉基类对象且程序的行为不变。可以保证继承体系的正确性,增强代码的可替代性和可扩展性,但可能需要更多的抽象和接口设计,增加设计复杂度。

class Rectangle {
public:virtual void setWidth(double width) {this->width = width;}virtual void setHeight(double height) {this->height = height;}double getArea() {return width * height;}
protected:double width;double height;
};class Square : public Rectangle {
public:void setWidth(double width) override {this->width = width;this->height = width;}void setHeight(double height) override {this->width = height;this->height = height;}
};void process(Rectangle& r) {r.setWidth(5);r.setHeight(4);assert(r.getArea() == 20); // Square 不能替代 Rectangle
}

4. 依赖倒置原则 (Dependency Inversion Principle, DIP)

- 高层模块不应该依赖于低层模块,二者都应该依赖于抽象;抽象不应该依赖于具体,具体应该依赖于抽象。可以减少类之间的耦合,提高系统的灵活性和可维护性,但需要更多的抽象和接口设计,增加设计复杂度。

class Keyboard {
public:std::string getInput() {return "User input";}
};class Monitor {
public:void display(std::string text) {// 显示文本}
};class Computer {
public:void run() {std::string input = keyboard.getInput();monitor.display(input);}
private:Keyboard keyboard;Monitor monitor;
};// 应用DIP后
class IInputDevice {
public:virtual std::string getInput() = 0;
};class IOutputDevice {
public:virtual void display(std::string text) = 0;
};class Keyboard : public IInputDevice {
public:std::string getInput() override {return "User input";}
};class Monitor : public IOutputDevice {
public:void display(std::string text) override {// 显示文本}
};class Computer {
public:Computer(IInputDevice* inputDevice, IOutputDevice* outputDevice): inputDevice(inputDevice), outputDevice(outputDevice) {}void run() {std::string input = inputDevice->getInput();outputDevice->display(input);}
private:IInputDevice* inputDevice;IOutputDevice* outputDevice;
};

5. 接口隔离原则 (Interface Segregation Principle, ISP)

- 客户端不应该被迫依赖它不使用的方法,即类间的依赖关系应该建立在最小的接口上。可以减少代码的冗余,提高系统的灵活性和可维护性,但可能导致接口数量增加,进而增加系统设计的复杂性。

class IWorker {
public:virtual void work() = 0;virtual void eat() = 0;
};class Worker : public IWorker {
public:void work() override {// 工作}void eat() override {// 吃饭}
};class Robot : public IWorker {
public:void work() override {// 工作}void eat() override {// 机器人不吃饭throw std::logic_error("Robots don't eat");}
};// 应用ISP后
class IWorkable {
public:virtual void work() = 0;
};class IFeedable {
public:virtual void eat() = 0;
};class Worker : public IWorkable, public IFeedable {
public:void work() override {// 工作}void eat() override {// 吃饭}
};class Robot : public IWorkable {
public:void work() override {// 工作}
};

6. 迪米特法则 (Law of Demeter, LoD)

- 一个对象应该对其他对象有最少的了解,即“只和你的直接朋友通信”。可以降低对象之间的耦合,提高系统的模块化,但可能增加系统的消息传递复杂度。

class Engine {
public:void start() {// 启动引擎}
};class Car {
public:Engine* getEngine() {return &engine;}
private:Engine engine;
};class Driver {
public:void startCar(Car& car) {car.getEngine()->start();}
};// 应用LoD后
class Engine {
public:void start() {// 启动引擎}
};class Car {
public:void start() {engine.start();}
private:Engine engine;
};class Driver {
public:void startCar(Car& car) {car.start();}
};

7. 合成复用原则 (Composite Reuse Principle, CRP)

- 尽量使用对象组合,而不是继承来达到复用的目的。这样可以减少类之间的耦合,提高系统的灵活性,但可能需要更多的对象管理代码,增加系统的复杂度。

class Engine {
public:void start() {// 启动引擎}
};class ElectricEngine : public Engine {
public:void start() override {// 启动电动引擎}
};class Car {
public:void start() {engine.start();}
private:Engine engine;
};// 应用CRP后
class Engine {
public:virtual void start() = 0;
};class GasEngine : public Engine {
public:void start() override {// 启动燃气引擎}
};class ElectricEngine : public Engine {
public:void start() override {// 启动电动引擎}
};class Car {
public:Car(Engine* engine) : engine(engine) {}void start() {engine->start();}
private:Engine* engine;
};

8. 最少知识原则 (Least Knowledge Principle, LKP)

- 一个对象应尽可能少地了解其他对象,以减少相互依赖。可以降低对象之间的耦合,提高系统的灵活性和可维护性,但也有可能需要引入更多的接口或中介,增加系统的复杂度。

class Engine {
public:void start() {// 启动引擎}
};class Transmission {
public:void shiftGear() {// 换挡}
};class Car {
public:Engine* getEngine() {return &engine;}Transmission* getTransmission() {return &transmission;}
private:Engine engine;Transmission transmission;
};class Driver {
public:void startCar(Car& car) {car.getEngine()->start();car.getTransmission()->shiftGear();}
};// 应用LKP后
class Engine {
public:void start() {// 启动引擎}
};class Transmission {
public:void shiftGear() {// 换挡}
};class Car {
public:void start() {engine.start();transmission.shiftGear();}
private:Engine engine;Transmission transmission;
};class Driver {
public:void startCar(Car& car) {car.start();}
};

C++中的23种设计模式

C++中的23种设计模式_c++设计模式-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/28744.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jQuery UI 实例

jQuery UI 实例 jQuery UI 是一个建立在 jQuery JavaScript 库之上的用户界面交互、特效、小部件和主题框架。它提供了一系列的预构建组件,使得开发者能够轻松地创建具有丰富交互性的网页。本篇文章将通过一系列实例,介绍如何使用 jQuery UI 来增强网页…

统计检验与机器学习双管齐下:深入解析糖尿病风险

1.项目背景 糖尿病是一种影响全球数百万人的慢性疾病,对公共健康构成重大威胁。准确预测糖尿病的发病风险对于早期干预和预防至关重要。通过机器学习模型分析影响糖尿病的主要因素,可以帮助医疗从业者更好地了解病因和风险因素,从而制定有效的预防和治疗策略。本项目通过可…

PyCharm配置教程,手把手教你如何配置

文章目录 引言1. 安装 PyCharm1.1 下载和安装1.2 初次启动 2. 基本配置2.1 设置界面2.2 常用配置项 3. 项目配置3.1 创建新项目3.2 配置解释器 4. 虚拟环境配置4.1 创建虚拟环境4.2 使用已有虚拟环境4.3 管理依赖 5. 插件和扩展5.1 安装插件5.2 推荐插件 6. 调试配置6.1 配置调…

【计算机毕业设计】234基于微信小程序的中国各地美食推荐平台

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

可穿戴设备:苹果“吃老底”、华为“忙复苏”、小米“再扩容”

配图来自Canva可画 随着产品功能的创新,可穿戴设备不再被简单地视为手机的延伸,而是被当成一种独立的、具有独特功能和优势的产品,受到了越来越多人的青睐。 一方面,技术的进步使得可穿戴设备在功能、性能和使用体验上得到显著提…

Golang | Leetcode Golang题解之第160题相交链表

题目: 题解: func getIntersectionNode(headA, headB *ListNode) *ListNode {if headA nil || headB nil {return nil}pa, pb : headA, headBfor pa ! pb {if pa nil {pa headB} else {pa pa.Next}if pb nil {pb headA} else {pb pb.Next}}retu…

IDEA快速入门03-代码头统一配置

三、代码规范配置 3.1 文件头和作者信息 配置入口:依次打开 File -> Settings -> Editor -> File and Code Templates。 Class /*** Copyright (C) 2020-${YEAR}, Glodon Digital Supplier & Purchaser BU.* * All Rights Reserved.*/ #if (${PACKA…

pdf只要其中一页,pdf只要其中几页怎么弄

在现代办公和学习环境中,pdf文件因其跨平台、保持原样等优点而被广泛使用。然而,有时我们需要一个pdf其中页或其中几页,以便更好地管理和使用其中的内容。本文将详细介绍几种拆分pdf文件的方法,帮助您轻松应对各种拆分需求。 打开…

开源项目推荐

这个资源列表集合了.NET开发领域的优秀工具、库、框架和软件等, 如果您目前研究开源大模型项目,请参考热门开源大模型项目推荐链接如下:https://blog.csdn.net/hefeng_aspnet/article/details/139669116 欢迎各位小伙伴收藏、点赞、留言、评论…

图像识别技术在虚拟现实与增强现实中的应用

图像识别技术在虚拟现实(VR)与增强现实(AR)领域中的应用广泛而深入,为用户提供了丰富多样的交互体验。以下是关于图像识别技术在这两个领域中的具体应用: 虚拟现实(VR)中的应用 虚…

请不要自嗨,B端系统颜值不过关,功能再强大可能等于0

我们见过形形色色的系统,有不少老铁费劲开发出来的管理系统,输在了颜值上。商务人员觉得么有信心,就不敢推荐,客户中间人觉得拿不出手,就不会向上层重点推荐,有时候即便客户购买了,也是被客户的…

你还记得java核心基础类Object么?

Object 类的常见方法有哪些? Object 类是一个特殊的类,是所有类的父类。它主要提供了以下 11 个方法: /** * 尚硅谷2024新版3小时速通Docker教程 * https://www.sanzhishu.top/2696.html */// native 方法,用于返回当前运行时对…

【Linux】使用 iptables 验证访问HDFS 所使用到的端口

目录 ​编辑 一、实操背景 二、iptables 简介 三、模拟操作 一、实操背景 背景: 在客户有外网的服务器需要访问内网大数据集群HDFS,使用iptable模拟测试需要开放的端口。 二、iptables 简介 具体介绍看文章: 【Linux】Iptables 详解与实战…

并发控制:确保数据一致性的策略

引言 ​ 在现代软件开发中,尤其是在涉及高并发场景的应用,如在线购物、金融交易等,保证数据操作的原子性和一致性是至关重要的。本文将深入探讨并发环境下常见的问题,以及如何通过先进的技术手段确保数据的准确性和安全性。 案例…

安全生产管理系统——特殊作业管控

特殊作业环节面临事故多发、频发、死亡率高,如何做到有效管理是一大考验,进行系统全面的规整很有必要。安全生产管理系统中特殊作业管理通过整合资源和采用信息化技术对动火、受限空间、盲板抽堵、高处、吊装、临时用电、动土、断路等特殊作业全过程管理…

让UI和前端相亲相爱的秘诀:与人方便,自己方便。

在实际项目开发中,UI设计师和前端开发人员经常互撕,这背后的原因是什么?有什么办法可以避么?贝格前端工场在这里为大家解读一下。 一、UI和前端互厮的原因有哪些? 导致UI和前端在写作过程中出现盲区导致互撕的原因可…

HTML表单深度解析:构建互动的网页界面

表单是HTML中用于收集用户输入信息的重要元素&#xff0c;是网页与用户交互的关键组件。以下是一个典型的HTML表单示例&#xff0c;我们将会详细解析其中的各个元素及属性含义。 <form action"https://xx.xxx.xx/search" target"_self" method"ge…

SAP 外币金额汇率转换

一、说明 汇率维护在ERP中可以使用事务代码OB07或者OB08&#xff0c;每次不同币别的汇率更改在正式生产系统中都会新创建一条记录&#xff0c;保存之后会存储在表TCURR中&#xff0c;可以通过函数CONVERT_TO_LOCAL_CURRENCY转换获取&#xff08;注意函数Exporting中各个参数一定…

代码随想录算法训练营DAY38| 理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

理论基础 动态规划的解题步骤 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 509. 斐波那契数 题目链接&#xff1a;509. 斐波那契数 class Solution(object):def fib(self, n):""":t…

第二十章 迭代器模式

目录 1 迭代器模式介绍 2 迭代器模式原理 3 迭代器模式实现 4 迭代器模式应用实例 5 迭代器模式总结 1 迭代器模式介绍 迭代器模式(Iterator pattern)又叫游标&#xff08;Cursor&#xff09;模式&#xff0c;它的原始定义是&#xff1a;迭代器提供一种对容器对象中的各…