【C++设计模式】依赖倒转原则
2023年8月30日,周三上午
目录
- 概述
- 含义
- 举个简单的例子
- 传统做法
- 使用依赖倒转原则
- 代码说明
- 再举一个具体的例子
- 以生活为例
概述
依赖倒转原则(Dependency Inversion Principle,DIP)是面向对象设计中的一个基本原则。
含义
高层模块不应该依赖低层模块,两者都应该依赖其抽象。
也就是说:
- 高层模块不应该直接依赖低层模块,两者之间应使用抽象来解耦。
- 具体实现应该依赖抽象,而不应该依赖细节。
- 抽象不应该依赖细节,细节应该依赖抽象。
举个简单的例子
- 高层模块:用户模块
- 低层模块:数据库模块
- 抽象:接口或抽象基类
传统做法
这违反了依赖倒转原则,因为高层用户模块直接依赖了低层数据库模块。
用户模块 -> 直接依赖数据库模块
使用依赖倒转原则
- 定义一个数据库操作的接口或抽象基类
- 数据库模块实现这个接口/基类
- 用户模块只依赖接口/基类,通过接口/基类与数据库模块解耦
依赖 实现
用户模块 -----> 接口/抽象基类<-----数据库模块
这样一来,用户模块与数据库模块的依赖关系就通过抽象进行了解耦。如果需要替换数据库,只需要修改数据库模块的实现,不影响用户模块。
总之,依赖倒转原则通过抽象层解耦高低层模块的依赖关系,提高了模块的独立性、可扩展性和可维护性。
代码说明
这里用一个简单的代码例子来说明依赖倒转原则。
依赖 实现
UserModule -----> 抽象类IDataBase<-----MysqlDatabase
首先定义一个数据库操作的接口:
// 抽象接口
class IDatabase {
public:virtual void Insert(const string& data) = 0;virtual void Select() = 0;
};
然后实现这个接口的具体数据库类:
// 具体实现
class MysqlDatabase : public IDatabase{
public:void Insert(const string& data) override {// 具体插入逻辑}void Select() override {// 具体查询逻辑 }
};
用户模块只依赖接口,不依赖具体实现:
// 用户模块
class UserModule {
private:IDatabase* db;public:UserModule(IDatabase* db) : db(db) {}void Run() {// ...db->Insert("some data");db->Select();}
};
在主函数中:
int main() {MysqlDatabase mysql;UserModule user(&mysql);user.Run();return 0;
}
在这个程序里:
- 用户模块只依赖抽象接口IDatabase,不依赖具体的MysqlDatabase类。
- MysqlDatabase实现了IDatabase接口。
- 通过接口解耦了用户模块和数据库模块的依赖关系。
如果需要替换数据库,只需要修改MysqlDatabase实现,而不影响用户模块。这就是依赖倒转原则的实现。
再举一个具体的例子
在windows平台上用这套
依赖 实现
DrawingProgram -----> 抽象类IShape<-----RectangleOnWindows
在Linux平台上用这套
依赖 实现
DrawingProgram -----> 抽象类IShape<-----RectangleOnLinux
#include<iostream>class IShape {
public:virtual void draw() = 0;
};//在windows平台上画矩形
class RectangleOnWindows : public IShape {
public:void draw() override {std::cout << "在Windows上画矩形" << std::endl;std::cout << "先画左边和右边,再画上边和下边" << std::endl;}
};//在Linux平台上画矩形
class RectangleOnLinux : public IShape {
public:void draw() override {std::cout << "在Linux上画矩形" << std::endl;std::cout << "先画上边和左边,再画下边和右边" << std::endl;}
};class DrawingProgram {
private:IShape* shape;public:DrawingProgram(IShape* shape) {this->shape = shape;}void run() {shape->draw();}
};
int main() {//在Windows平台上用这一套RectangleOnWindows ROW;DrawingProgram program(&ROW);program.run();//在Linux平台上用这一套
// RectangleOnLinux ROL;
// DrawingProgram program(&ROL);
// program.run();return 0;
}
这这个程序中:
- 绘图程序只依赖形状接口,不依赖具体形状类。
- 形状类实现了形状接口。
- 通过接口解耦了绘图程序和形状类的依赖关系。
如果需要添加新的形状,只需要实现形状接口,不影响绘图程序。这就是一个完整的依赖倒转原则示例。
以生活为例
电脑中的主板就是最好的一个依赖倒转原则例子,
在主板上有非常多的硬件接口,用来安装内存、硬盘、电源等等,
这些硬件接口就相当于抽象类,
正是因为有了接口,才能在一块主板上安装不同品牌、不同厂商生产的内存条、硬盘、电源等等。
如果主板上没有这些硬件接口,而是直接让主板与某个品牌的内存条连接,
那么当这个内存条坏了,你就只能买这个品牌的内存条,用其他品牌的没用,
因为这个主板是针对这个品牌的内存条设计的,没办法做到抽象,也就只能用这个品牌的。
相关文章:
【C++设计模式】依赖倒转原则
2023年8月30日,周三上午 目录 概述含义举个简单的例子传统做法使用依赖倒转原则代码说明再举一个具体的例子以生活为例 概述 依赖倒转原则(Dependency Inversion Principle,DIP)是面向对象设计中的一个基本原则。 含义 高层模块不应该依赖低层模块,两者都应该依…...
浙江首例!金华银行基于完全国产自研数据库构建新一代核心系统
6 月 12 日,金华银行举行“星辉工程”核心项目群上线发布会,新一代核心系统部署在国产分布式数据库 OceanBase 上,实现系统的高可用、高性能、国产升级。据悉,这是浙江省首例基于完全国产自研数据库落地的银行核心系统。 金华银行…...
ASP.NET Core 中的 静态文件
Static Files Static Files 包括 HTML,CSS,图片,JavaScript,以及其他静态资源文件。 即网站本身的内容。 Static Files 服务 Static Files 保存在项目的 Web Root 目录,即 wwwroot 文件夹中。 而wwwroot目录是Conte…...
2023年天府杯——C 题:码头停靠问题
问题背景: 某个港口有多个不同类型的码头,可以停靠不同种类的船只。每 艘船只需要一定的时间来完成装卸货物等任务,并且每个码头有容量 限制和停靠时间限制。港口需要在保证收益的情况下,尽可能地提高 运营效率和降低成本。同…...
集丰照明|汽车美容店设计,装修色彩灯光搭配方法
正确处理好店面的空间设计。 店铺各个功能区设计要合理,衔接合理,这样既能提高员工的工作效率也能提高顾客的满意度。合理安排店铺的空间分配, 要给顾客一种舒适度,既不能让顾客感觉到过于拥挤,又不能浪费店铺的有限空…...
性能提升3-4倍!贝壳基于Flink + OceanBase的实时维表服务
作者介绍:肖赞,贝壳找房(北京)科技有限公司 OLAP 平台负责人,基础研发线大数据平台部架构师。 贝壳找房是中国最大的居住服务平台。作为居住产业数字化服务平台,贝壳致力于推进居住服务的产业数字化、智能…...
取数组中每个元素的最高位
1 题目 /*程序将一维数组a中N个元素的最高位取出,保存在一维数组b的对应位置。 程序运行结果为: a:82 756 71629 5 2034 b: 8 7 7 5 2 */ 2 思考 简单来说就是取一个数据的最高位。 一开始的笨方法没有办法判断数据的长度,后来…...
Docker一键部署Nacos
官方参考文档: https://nacos.io/zh-cn/docs/quick-start-docker.html 本人实践 一、创建数据库&数据表 使用sql脚本创建:https://github.com/alibaba/nacos/blob/master/config/src/main/resources/META-INF/nacos-db.sql 二、新建文件夹并赋权…...
【数学建模】-- 模糊综合评价
模糊综合评价(Fuzzy Comprehensive Evaluation)是一种用于处理不确定性和模糊性信息的决策分析方法。它通常用于解决复杂的多指标决策问题,其中各指标之间可能存在交叉影响和模糊性的情况。模糊综合评价通过将不确定性和模糊性量化࿰…...
Java 数据库改了一个字段, 前端传值后端接收为null问题解决
前端传值后端为null的原因可能有很多种,我遇到一个问题是,数据库修改了一个字段,前端传值了,但是后台一直接收为null值, 原因排查: 1、字段没有匹配上,数据库字段和前端字段传值不一致 2、大…...
lnmp架构-mysql1
1.MySQL数据库编译 make完之后是这样的 mysql 初始化 所有这种默认不在系统环境中的路径里 就这样加 这样就可以直接调用 不用输入路径调用 2.初始化 重置密码 3.mysql主从复制 配置master 配置slave 当master 端中还没有插入数据时 在server2 上配slave 此时master 还没进…...
Threadlocal在项目中的应用
ThreadLocal为每一线程提供一份单独的存储空间,具有线程隔离的作用 PageHelper.startPage()方法使用ThreadLocal来保存分页参数,保证线程安全性。PageHelper通过集成MyBatis的拦截器机制来实现对SQL语句的拦截和修改 项目中使用了ThreadLocal保存每个线程…...
个性化定制你的AI助手,AI指令提示词专家
『个性化定制你的AI助手』围观不如下场!需要学习AI指令提升能力的,精准输出想要内容的,快来订阅 javastarboy『AI指令保姆级拆解』合集! ▶️你是否尚未挖掘到 AI 的潜力? ▶️你是否经常遇到“答非所问”的“人工智障…...
mongodb聚合排序的一个巨坑
现象: mongodb cpu动不动要100%,如下图 分析原因: 查看慢日志发现,很多条这样的查询,一直未执行行完成,占用大量的CPU [{$match: {"tags.taskId": "64dae0a9deb52d2f9a1bd71e",grnty: …...
无涯教程-分类算法 - 随机森林
随机森林是一种监督学习算法,可用于分类和回归,但是,它主要用于分类问题,众所周知,森林由树木组成,更多树木意味着更坚固的森林。同样,随机森林算法在数据样本上创建决策树,然后从每…...
c#常见的排序算法
在C#中,常见的排序算法包括以下几种: 1. 冒泡排序(Bubble Sort):比较相邻的元素,如果顺序不对就交换它们,重复多次直到排序完成。 2. 插入排序(Insertion Sort)…...
Redis 持久化和发布订阅
一、持久化 Redis 是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以 Redis 提供了持久化功能! 1.1、RDB(Redis DataBase) 1.1.1 …...
k8s使用ECK(2.4)形式部署elasticsearch+kibana-http协议
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、准备elasticsearch-cluster.yaml二、部署并测试总结 前言 之前写了eck2.4部署eskibana,默认的话是https协议的,这里写一个使用http…...
[maven]关于pom文件中的<relativePath>标签
关于pom文件中的<relativePath>标签 为什么子工程要使用relativePath准确的找到父工程pom.xml.因为本质继承就是pom的继承。父工程pom文件被子工程复用了标签。(可以说只要我在父工程定义了标签,子工程就可以没有,因为他继承过来了&…...
11. 网络模型保存与读取
11.1 网络模型保存(方式一) import torchvision import torch vgg16 torchvision.models.vgg16(pretrainedFalse) torch.save(vgg16,"./model/vgg16_method1.pth") # 保存方式一:模型结构 模型参数 print(vgg16) 结果: VGG((feature…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
