当前位置: 首页 > news >正文

C++那些事之依赖注入

C++那些事之依赖注入

最近星球里面有个小伙伴让更新一下依赖注入,于是写出了这篇文章,来从实际的例子讲解,本文会讲解一些原理与实现,完整的实现代码懒人版放在星球中,我们开始正文。

大纲:

  • 直接依赖

  • 接口依赖注入

  • 模版依赖注入

依赖注入是一种常用的设计模式,通常会采用接口/模版的方式提高代码的可测性与维护性,下面我们来举个例子。

假设有一个用户服务类UserService,需要通过HTTP客户端与远程服务器进行通信,在这种情况下我们可能会写出如下三种实现。

ce3ea3a333742336550a2dc7fa8e704f.png

1.直接依赖

UserService内部直接依赖HttpClient,例如:

class HttpClient {public:std::string Get(const std::string& url);void Post(const std::string& url, const std::string& data);
};class UserService {private:HttpClient m_httpClient;
};

UserService内部通常会有一些方法去操作m_httpClient,这种方式简单粗暴,但是UserService与具体的HttpClient相耦合,导致难以替换依赖对象,也难以进行单元测试。

于是引出了后面两个方法。

2.接口依赖注入

我们的目标是期望测试的时候很方便的测试,而不需要创建一个具体的类,可以由用户mock出一个类去测试,那么我们可以想到接口,将HttpClient抽出来,得到:

struct IHttpClient {virtual std::string Get(const std::string& url) = 0;virtual void Post(const std::string& url, const std::string& data) = 0;virtual ~IHttpClient() = default;
};
class UserService {private:std::unique_ptr<IHttpClient> m_httpClient;
};

那么在测试的时候便可以mock出一个client进行测试,例如:

class MockHttpClient : public IHttpClient {
public:MOCK_METHOD(std::string, Get, (const std::string& url), (override));MOCK_METHOD(void, Post, (const std::string& url, const std::string& data), (override));
};auto mockHttpClient = std::make_unique<MockHttpClient>();
UserService userService(std::move(mockHttpClient));

经过以上改造,我们可以做到:

  • 在 .cc 文件中隐藏实现细节

  • 针对抽象接口工作

  • 在对象构造期间注入依赖项

3.模版依赖注入

模板依赖注入通过C++模板技术,将依赖对象作为模板参数传递给UserService。在实例化模板时,指定具体的HTTP客户端实现。这种方法在编译时解决依赖问题,无需虚函数调用,提高了性能。同时,也使得UserService类可以灵活地与不同的HTTP客户端实现进行集成,并且易于进行单元测试。

template <typename THttpClient>
class UserService {private:THttpClient m_httpClient;
};

在这种情况下比较好测试,例如:

UserService<MockHttpClient> userService;

这种方式有如下好处:

  • 在模板实例化期间注入依赖项

  • 无需虚拟调用(注意 THttpClient 不是接口,因此可以在编译时解析调用)

以上便是本节要讲的所有内容,本节完整代码放于星球,欢迎订阅下载!

跟我一起实践写代码,戳这里呀~

118afdd0374239d7947f367bf69ea2b0.jpeg

往期推荐:

向量数据库milvus源码剖析之开篇

热度更新,手把手实现工业级线程池

d46b02d51af29b0cc49013a36bc758ce.jpeg

相关文章:

C++那些事之依赖注入

C那些事之依赖注入 最近星球里面有个小伙伴让更新一下依赖注入&#xff0c;于是写出了这篇文章&#xff0c;来从实际的例子讲解&#xff0c;本文会讲解一些原理与实现&#xff0c;完整的实现代码懒人版放在星球中&#xff0c;我们开始正文。 大纲&#xff1a; 直接依赖接口依赖…...

克隆的TrinityCore服务器网速慢卡顿问题的解决(未解决)

一台TrinityCore服务器&#xff0c;采用的是备份克隆安装的方式&#xff0c;在FreeBSD bhyve 中安装Ubuntu&#xff0c;安装细节见如下两篇文档&#xff1a;尝试在FreeBSD 的jail、bhyve里安装TrinityCore-CSDN博客 备份和镜像TrinityCore_魔兽世界 updating auth database...…...

独立站外链如何影响搜索引擎排名?

独立站的外链对搜索引擎排名有着非常重要的影响。简单来说&#xff0c;外链就像是别的网站对你的网站投的信任票。每一条外链都告诉搜索引擎&#xff1a;“这个网站的内容是有价值的&#xff0c;值得推荐。”因此&#xff0c;外链的数量和质量直接影响你的网站在搜索引擎中的排…...

java设计模式:03-04-装饰器模式

装饰器模式&#xff08;Decorator Pattern&#xff09; 装饰器模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其结构。装饰器模式通过创建一个装饰类来包装原有的类&#xff0c;…...

通过splunk web服务将服务器上文件下载到本地

1. 需求说明 工作中经常遇到需要将服务器上的文件下载到本地&#xff0c;但是由于各种网络环境限制&#xff0c;没办法使用winscp或者xftp工具&#xff0c;那么如何将服务器上的文件下载下来呢&#xff1f; 这里提供一种思路: 如果服务器上安装有web服务&#xff0c;可将待下…...

Node.js 路由

Node.js 路由 介绍 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它允许开发者使用 JavaScript 编写服务器端代码。Node.js 的一个核心特性是其事件驱动和非阻塞 I/O 模型,这使得它非常适合处理高并发和 I/O 密集型的应用程序。在 Node.js 中,路由是指确定应…...

Adobe国际认证详解-网页设计认证专家行业应用场景解析

在当今数字化时代&#xff0c;网页设计已成为各行各业不可或缺的一环。而网页设计认证专家&#xff0c;作为经过Adobe国际认证体系严格考核的专业人才&#xff0c;正逐渐成为行业内炙手可热的存在。他们凭借深厚的网页设计理论基础和实践经验&#xff0c;为各行各业提供了高质量…...

ESC(ELectronic Stability Control,电子稳定控制系统)

ESC通过实时监测车辆的动态参数&#xff0c;以及车辆轮胎的实际运动状态&#xff0c;通过调节车辆制动系统和发动机输出力&#xff0c;使车辆在紧急或危险情况下保持稳定&#xff0c;防止侧滑和失控。 ESC组成部分 传感器&#xff1a;用于检测车辆的动态参数&#xff0c;如车…...

减分兔搜题-12123学法减分20题目及答案 #媒体#职场发展

对于即将参加驾驶考试的朋友来说&#xff0c;掌握一些经典题目和答案至关重要。今天&#xff0c;我就为大家带来了这样一份干货——20道驾驶考试题目和答案&#xff0c;助你轻松应对考试&#xff01;这些题目不仅包括了考试中常考的内容&#xff0c;还有针对难点和重点的详细解…...

java用freemarker导出word

freemarker导出word 第一步、将word转换为xml格式第二步、将转换后的xml文件修改后缀为ftl后复制到项目 resources 目录下&#xff08;可以自己新建一个文件夹放在文件夹中&#xff09;第三步、格式化xml代码&#xff08;如果问价太大可能会无法格式化&#xff09;这时候需要在…...

CH01_WPF概述

第1章&#xff1a;WPF概述 本章目标 了解Windows图形演化了解WPF高级API了解分辨率无关性概念了解WPF体系结构了解WPF 4.5 WPF概述 ​ 欢迎使用 Windows Presentation Foundation (WPF) 桌面指南&#xff0c;这是一个与分辨率无关的 UI 框架&#xff0c;使用基于矢量的呈现引…...

秒懂设计模式--学习笔记(11)【结构型-享元模式】

目录 10、享元模式10.1 享元模式10.2 举例10.2.1 马赛克10.2.2 游戏地图&#xff08;以草原地图作为范例&#xff09; 10.3 总结 10、享元模式 10.1 享元模式 “享元”则是共享元件的意思享元模式的英文flyweight是轻量级的意思&#xff0c;这就意味着享元模式能使程序变得更…...

Python爬虫——1爬虫基础(一步一步慢慢来)

一、爬虫是什么&#xff1f; &#xff08;spider&#xff09; Python 爬虫是利用编程语言 Python 来获取互联网上的数据的技术。它可以自动化地访问网页、提取信息并进行数据处理。以下是Python爬虫的基础知识和步骤&#xff1a; 主要特点和功能&#xff1a; 自动化浏览&#…...

【js自学打卡9】抛出异常 / 幂计算 / 发布订阅 / map小知识点

1. 抛出异常的写法 抛出一个简单的字符串错误 throw Error2; // 抛出一个字符串抛出一个Error对象 throw new Error(出错了&#xff01;);抛出一个自定义错误对象 function UserError(message) {this.message message;this.name "UserError"; } throw new User…...

ArcGIS Pro SDK (九)几何 7 多点

ArcGIS Pro SDK &#xff08;九&#xff09;几何 7 多点 文章目录 ArcGIS Pro SDK &#xff08;九&#xff09;几何 7 多点1 构造多点 - 从映射点的枚举2 构造多点 - 使用 MultipointBuilderEx3 修改多点的点4 从多点检索点、2D 坐标、3D 坐标 环境&#xff1a;Visual Studio 2…...

服务器注意事项

1. 远程服务器不允许关机&#xff0c;只能重启&#xff1b; 2. 重启服务器应关闭服务&#xff1b; 3. 不要在服务器访问高峰运行高负载命令&#xff1b; 4. 远程配置防火墙是不要把自己踢出服务器&#xff1b; 5. 制定合理的密码规范并定期更新&#xff1b; 6. 合理分配权…...

学生信息管理系统设计

学生信息管理系统的设计是一个综合性的项目&#xff0c;涉及到数据的存储、检索、更新和删除等基本操作&#xff0c;同时也需要考虑系统的易用性、安全性和扩展性。以下是一些关键步骤和要素&#xff0c;用于指导设计这样一个系统&#xff1a; 1. 需求分析 目标用户&#xff…...

Python求均值,方差,标准差

参考链接&#xff1a;变异系数&#xff08;Coefficient of Variation,COV&#xff09;和协方差&#xff08;Covariance, Cov&#xff09;-CSDN博客 参考链接&#xff1a;pandas中std和numpy的np.std区别_numpy pandas std-CSDN博客 在计算蛋白质谱数据中的每个蛋白对应的变异…...

DDei在线设计器-HTML渲染

Html渲染 HtmlViewer插件通过将一个外部DIV附着在图形控件上&#xff0c;从而改变原有图形的显示方式。允许使用者自己定义HTML通过HTML元素。本示例演示了通过Html来扩展渲染图形&#xff0c;从而获得更加丰富的图形展现。 通常情况下&#xff0c;我们创建的图形控件&#xff…...

【React Hooks原理 - useSyncExternalStore】

概述 在React项目中说到状态管理&#xff0c;我们第一时间想到的就是使用useState、useReducer这种Hooks来进行状态管理。但是这种是针对React内部的状态&#xff0c;如果有时候我们需要订阅外部的状态并影响React组件的更新的话&#xff0c;那通过这种内部状态管理API显然不能…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...