C++那些事之依赖注入
C++那些事之依赖注入
最近星球里面有个小伙伴让更新一下依赖注入,于是写出了这篇文章,来从实际的例子讲解,本文会讲解一些原理与实现,完整的实现代码懒人版放在星球中,我们开始正文。
大纲:
直接依赖
接口依赖注入
模版依赖注入
依赖注入是一种常用的设计模式,通常会采用接口/模版的方式提高代码的可测性与维护性,下面我们来举个例子。
假设有一个用户服务类UserService,需要通过HTTP客户端与远程服务器进行通信,在这种情况下我们可能会写出如下三种实现。
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 不是接口,因此可以在编译时解析调用)
以上便是本节要讲的所有内容,本节完整代码放于星球,欢迎订阅下载!
跟我一起实践写代码,戳这里呀~
往期推荐:
向量数据库milvus源码剖析之开篇
热度更新,手把手实现工业级线程池
相关文章:
C++那些事之依赖注入
C那些事之依赖注入 最近星球里面有个小伙伴让更新一下依赖注入,于是写出了这篇文章,来从实际的例子讲解,本文会讲解一些原理与实现,完整的实现代码懒人版放在星球中,我们开始正文。 大纲: 直接依赖接口依赖…...
克隆的TrinityCore服务器网速慢卡顿问题的解决(未解决)
一台TrinityCore服务器,采用的是备份克隆安装的方式,在FreeBSD bhyve 中安装Ubuntu,安装细节见如下两篇文档:尝试在FreeBSD 的jail、bhyve里安装TrinityCore-CSDN博客 备份和镜像TrinityCore_魔兽世界 updating auth database...…...
独立站外链如何影响搜索引擎排名?
独立站的外链对搜索引擎排名有着非常重要的影响。简单来说,外链就像是别的网站对你的网站投的信任票。每一条外链都告诉搜索引擎:“这个网站的内容是有价值的,值得推荐。”因此,外链的数量和质量直接影响你的网站在搜索引擎中的排…...
java设计模式:03-04-装饰器模式
装饰器模式(Decorator Pattern) 装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰器模式通过创建一个装饰类来包装原有的类,…...
通过splunk web服务将服务器上文件下载到本地
1. 需求说明 工作中经常遇到需要将服务器上的文件下载到本地,但是由于各种网络环境限制,没办法使用winscp或者xftp工具,那么如何将服务器上的文件下载下来呢? 这里提供一种思路: 如果服务器上安装有web服务,可将待下…...
Node.js 路由
Node.js 路由 介绍 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它允许开发者使用 JavaScript 编写服务器端代码。Node.js 的一个核心特性是其事件驱动和非阻塞 I/O 模型,这使得它非常适合处理高并发和 I/O 密集型的应用程序。在 Node.js 中,路由是指确定应…...
Adobe国际认证详解-网页设计认证专家行业应用场景解析
在当今数字化时代,网页设计已成为各行各业不可或缺的一环。而网页设计认证专家,作为经过Adobe国际认证体系严格考核的专业人才,正逐渐成为行业内炙手可热的存在。他们凭借深厚的网页设计理论基础和实践经验,为各行各业提供了高质量…...
ESC(ELectronic Stability Control,电子稳定控制系统)
ESC通过实时监测车辆的动态参数,以及车辆轮胎的实际运动状态,通过调节车辆制动系统和发动机输出力,使车辆在紧急或危险情况下保持稳定,防止侧滑和失控。 ESC组成部分 传感器:用于检测车辆的动态参数,如车…...
减分兔搜题-12123学法减分20题目及答案 #媒体#职场发展
对于即将参加驾驶考试的朋友来说,掌握一些经典题目和答案至关重要。今天,我就为大家带来了这样一份干货——20道驾驶考试题目和答案,助你轻松应对考试!这些题目不仅包括了考试中常考的内容,还有针对难点和重点的详细解…...
java用freemarker导出word
freemarker导出word 第一步、将word转换为xml格式第二步、将转换后的xml文件修改后缀为ftl后复制到项目 resources 目录下(可以自己新建一个文件夹放在文件夹中)第三步、格式化xml代码(如果问价太大可能会无法格式化)这时候需要在…...
CH01_WPF概述
第1章:WPF概述 本章目标 了解Windows图形演化了解WPF高级API了解分辨率无关性概念了解WPF体系结构了解WPF 4.5 WPF概述 欢迎使用 Windows Presentation Foundation (WPF) 桌面指南,这是一个与分辨率无关的 UI 框架,使用基于矢量的呈现引…...
秒懂设计模式--学习笔记(11)【结构型-享元模式】
目录 10、享元模式10.1 享元模式10.2 举例10.2.1 马赛克10.2.2 游戏地图(以草原地图作为范例) 10.3 总结 10、享元模式 10.1 享元模式 “享元”则是共享元件的意思享元模式的英文flyweight是轻量级的意思,这就意味着享元模式能使程序变得更…...
Python爬虫——1爬虫基础(一步一步慢慢来)
一、爬虫是什么? (spider) Python 爬虫是利用编程语言 Python 来获取互联网上的数据的技术。它可以自动化地访问网页、提取信息并进行数据处理。以下是Python爬虫的基础知识和步骤: 主要特点和功能: 自动化浏览&#…...
【js自学打卡9】抛出异常 / 幂计算 / 发布订阅 / map小知识点
1. 抛出异常的写法 抛出一个简单的字符串错误 throw Error2; // 抛出一个字符串抛出一个Error对象 throw new Error(出错了!);抛出一个自定义错误对象 function UserError(message) {this.message message;this.name "UserError"; } throw new User…...
ArcGIS Pro SDK (九)几何 7 多点
ArcGIS Pro SDK (九)几何 7 多点 文章目录 ArcGIS Pro SDK (九)几何 7 多点1 构造多点 - 从映射点的枚举2 构造多点 - 使用 MultipointBuilderEx3 修改多点的点4 从多点检索点、2D 坐标、3D 坐标 环境:Visual Studio 2…...
服务器注意事项
1. 远程服务器不允许关机,只能重启; 2. 重启服务器应关闭服务; 3. 不要在服务器访问高峰运行高负载命令; 4. 远程配置防火墙是不要把自己踢出服务器; 5. 制定合理的密码规范并定期更新; 6. 合理分配权…...
学生信息管理系统设计
学生信息管理系统的设计是一个综合性的项目,涉及到数据的存储、检索、更新和删除等基本操作,同时也需要考虑系统的易用性、安全性和扩展性。以下是一些关键步骤和要素,用于指导设计这样一个系统: 1. 需求分析 目标用户ÿ…...
Python求均值,方差,标准差
参考链接:变异系数(Coefficient of Variation,COV)和协方差(Covariance, Cov)-CSDN博客 参考链接:pandas中std和numpy的np.std区别_numpy pandas std-CSDN博客 在计算蛋白质谱数据中的每个蛋白对应的变异…...
DDei在线设计器-HTML渲染
Html渲染 HtmlViewer插件通过将一个外部DIV附着在图形控件上,从而改变原有图形的显示方式。允许使用者自己定义HTML通过HTML元素。本示例演示了通过Html来扩展渲染图形,从而获得更加丰富的图形展现。 通常情况下,我们创建的图形控件ÿ…...
【React Hooks原理 - useSyncExternalStore】
概述 在React项目中说到状态管理,我们第一时间想到的就是使用useState、useReducer这种Hooks来进行状态管理。但是这种是针对React内部的状态,如果有时候我们需要订阅外部的状态并影响React组件的更新的话,那通过这种内部状态管理API显然不能…...
C++STL初阶(7):list的运用与初步了解
在了解了vector之后,我们只需要简单学习List与vector不一样的接口即可 1.list的基本接口 1.1 iterator list中,与vector最大的区别就是迭代器由随机迭代器变成双向迭代器 string和vector中的迭代器都是随机迭代器,支持-等,而LIS…...
el-menu弹出菜单样式不生效
1. 使用 ruoyi 项目时出现的问题。 <template><el-menu:default-active"activeMenu":collapse"false":unique-opened"true"class"container":collapse-transition"true"mode"horizontal"><sideba…...
Springboot 3.x - Reactive programming (2)
三、WebFlux Blocking Web vs. Reactive Web Blocking Web (Servlet) and Reactive Web (WebFlux) have significant differences in several aspects. 1. Front Controller Servlet-Blocking Web: Uses DispatcherServlet as the front controller to handle all HTTP req…...
WPF+Mvvm 项目入门完整教程(一)
WPF+Mvvm 入门完整教程一 创建项目MvvmLight框架安装完善整个项目的目录结构创建自定义的字体资源下载更新和使用字体资源创建项目 打开VS2022,点击创建新项目,选择**WPF应用(.NET Framework)** 创建一个名称为 CommonProject_DeskTop 的项目,如下图所示:MvvmLight框架安装…...
[解决方法]git上传的项目markdown文件的图片无法显示
应该有不少初学者会遇到这种情况 以下是本人摸索出的解决方法 我使用的是typora,首先设置typora的图片设置 文件>偏好设置>图像 如下: 选择这个就会在此文件的同级目录下创建一个assets文件夹来存放此markdown文件的所有图片 然后勾选优先使用相…...
【React】使用 antd 加载组件实现 iframe 的加载效果
文章目录 代码实现: import { Spin } from antd; import { useState } from react;export default function () {const [loading, setLoading] useState(true);return (<div style{{ position: relative, height: 100% }}><Spinstyle{{ position: absolu…...
Python爬虫(1) --基础知识
爬虫 爬虫是什么? spider 是一种模仿浏览器上网过程的一种程序,可以获取一些网页的数据 基础知识 URL 统一资源定位符 uniform resource locator http: 超文本传输协议 HyperText Transfer Protocol 默认端口 80 https: 安全的超文本传输协议 security…...
云原生系列 - Jenkins
Jenkins Jenkins,原名 Hudson,2011 年改为现在的名字。它是一个开源的实现持续集成的软件工具。 官方网站(英文):https://www.jenkins.io/ 官方网站(中文):https://www.jenkins.io…...
django踩坑(四):终端输入脚本可正常执行,而加入crontab中无任何输出
使用crontab执行python脚本时,有时会遇到脚本无法执行的问题。这是因为crontab在执行任务时使用的环境变量与我们在终端中使用的环境变量不同。具体来说,crontab使用的环境变量是非交互式(non-interactive)环境变量,而终端则使用交互式(inter…...
计算机网络入门 -- 常用网络协议
计算机网络入门 – 常用网络协议 1.分类 1.1 模型回顾 计算机网络细分可以划为七层模型,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。而上三层可以划为应用层中。 1.2 分类 1.2.1 应用层 为用户的应用进程提供网络通信服务࿰…...
佛山个人网站建设/如何优化网站推广
Time Limit: 10 second Memory Limit: 2 MB 问题描述 简单的背包问题。设有一个背包,可以放入的重量为s。现有n件物品,重量分别为w1,w2.....wn(1≤i≤n),均为正整数,从n件物品中挑选若干件,使得…...
广州网站建设制作/长沙网站seo源头厂家
文章目录数字信号模拟信号带宽咋子数字信号中应用得更加广泛数字信号 数字信号系统中,带宽表示通讯线路传送数据的能力即在单位时间内通过网络中某一点的最高数据率,常用的单位为bps(又称为比特率—bit per second)在生活中常把b…...
wordpress log/品牌推广的作用
第一步进入wordpress后台(这是废话),找到“外观”模块下面 的“编辑”选项,进入主题编辑选项;这一步太简单,就不截图了。 在模版里面点击“顶部(header.php)”模版: 关键词如何添加 在左侧的header.php编辑框中找到<header>…...
做游戏直播什么游戏视频网站/永久免费不收费的污染app
1、变量名就像我们现实社会的名字,把一个值赋值给一个名字时,它会存储在内存中,称之为变量,大多数语言中,都把这种行为成为“给变量赋值”或“把值存储在变量中”。2、不过python与大多数其他计算机语言的做法稍有不同…...
旅游网站开发毕业论文前言/搜索引擎收录提交入口
用户在使用经典虚拟机时,经常会有如下疑问:门户主板页面中的 SSH/RDP 证书指纹这项信息是怎么来的?用途是什么?为什么有的时候为空?有没有对虚拟机使用有什么影响?以下我们进行一些基本的介绍: …...
网站后台如何上传ico图标/seo优化标题
精彩LINUX软件推荐发布时间:2011-09-13 22:07:21来源:红联作者:ICEENclementine #音乐播放器osdlyrics #歌词显示sudo add-apt-repository ppa:osd-lyrics/ppasudo apt-get update && sudo aptitude install osdlyricsUMPlayer #视频播放器Xchatsudo apt-get install s…...