设计模式-依赖注入

在软件开发中,我们经常遇到这样的情况:

一个类依赖于另一个类或者服务来完成某些功能。然而,硬编码的依赖关系会导致代码耦合度过高,难以测试和维护。为了解决这个问题,我们引入了一种设计模式——依赖注入(Dependency Injection,简称DI)。

一、原理

依赖注入是一种实现控制反转(Inversion of Control,简称IoC)的技术,其核心思想是将依赖关系从硬编码中解耦出来,通过外部注入的方式提供给需要依赖的对象。这样做的好处是增加了代码的灵活性和可测试性。

具体来说,依赖注入通常通过以下几种方式实现:

构造函数注入:
在对象的构造函数中传递依赖项。这是最常见且推荐的方式,因为它保证了对象在创建时就拥有了所有必需的依赖项。

属性注入:
通过设置对象的属性来注入依赖项。这种方式相对灵活,但可能导致对象在不完全初始化的状态下被使用。

接口注入:
定义一个接口来设置依赖项,然后由具体类实现该接口。这种方式在编译时保证了依赖项的设置,但在运行时可能需要额外的配置。

二、应用场景

依赖注入广泛应用于各种场景,尤其是当代码需要解耦和增强可测试性时。以下是一些典型的应用场景:

单元测试:
通过注入模拟对象(Mock Object)来替代实际依赖,从而轻松地对代码进行单元测试。

插件式架构:
通过依赖注入,可以轻松替换或扩展系统的某些部分,实现插件式架构。

跨平台应用:
对于需要跨平台运行的应用,可以通过依赖注入来抽象平台相关的实现,从而提高代码的可移植性。

三、依赖注入的优缺点

优点:

  • 解耦:降低了类之间的耦合度,使得代码更加灵活和可维护。

  • 可测试性:通过注入模拟对象,可以轻松地编写单元测试,而无需依赖实际的服务或组件。

  • 可扩展性:便于替换或扩展系统的某些部分,实现功能的灵活定制。

缺点:

  • 学习曲线:对于初学者来说,理解并正确应用依赖注入可能需要一定的时间。

  • 配置复杂性:在某些情况下,依赖注入可能导致额外的配置复杂性,尤其是在大型项目中。

  • 性能开销:虽然这个开销通常可以忽略不计,但在极端性能敏感的场景下,依赖注入可能会引入微小的性能开销。

四、C++使用示例

下面是一个简单的C++示例,展示了如何使用依赖注入来解耦日志记录功能:

// 定义日志输出接口
class ILogOutput {
public:virtual ~ILogOutput() = default;virtual void Output(const std::string& message) = 0;
};// 实现控制台日志输出
class ConsoleLogOutput : public ILogOutput {
public:void Output(const std::string& message) override {std::cout << message << std::endl;}
};// 实现文件日志输出
class FileLogOutput : public ILogOutput {
private:std::ofstream outputFile;
public:FileLogOutput(const std::string& filename) {outputFile.open(filename);}~FileLogOutput() {outputFile.close();}void Output(const std::string& message) override {outputFile << message << std::endl;}
};// 定义日志记录器,依赖于ILogOutput接口
class Logger {
private:ILogOutput* logOutput;
public:Logger(ILogOutput* output) : logOutput(output) {} // 构造函数注入void Log(const std::string& message) {logOutput->Output("Log: " + message);}
};// 在main函数中使用依赖注入
int main() {ConsoleLogOutput consoleOutput; // 控制台输出实例Logger consoleLogger(&consoleOutput); // 注入控制台输出到日志记录器consoleLogger.Log("Hello, Console!"); // 记录日志到控制台FileLogOutput fileOutput("log.txt"); // 文件输出实例,指定日志文件名Logger fileLogger(&fileOutput); // 注入文件输出到另一个日志记录器fileLogger.Log("Hello, File!"); // 记录日志到文件return 0;
}

在这个示例中,我们通过构造函数注入的方式,将不同的日志输出实现(控制台或文件)注入到日志记录器中。这样做的好处是,我们可以轻松地改变日志输出的方式,只需提供不同的ILogOutput实现即可。这种设计降低了Logger类与具体日志输出实现之间的耦合度,提高了代码的可测试性和可维护性。

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

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

相关文章

Parallels Desktop 20破解版(Mac虚拟机) v20.0.0 for Mac 最新商业版(支持M系列)

Parallels Desktop 20是一款目前功能最强大灵活度最高的虚拟机软件&#xff0c;可运行数千种 Windows 应用程序&#xff0c;如 Microsoft Office、Internet Explorer、Access、Quicken、QuickBooks、Visual Studio&#xff0c;甚至支持对图像要求较高的游戏和 CAD 项目&#xf…

渗透测试综合靶场 DC-2 通关详解

一、准备阶段 准备工具如Kali Linux&#xff0c;下载并设置DC-2靶场机。确保攻击机和靶机在同一网络段&#xff0c;通常设置为桥接模式或NAT模式。 1.1 靶机描述 Much like DC-1, DC-2 is another purposely built vulnerable lab for the purpose of gaining experience in …

python毕业设计作品:python手机数码商城系统毕业设计源代码作品和开题报告(Django框架)

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

算法知识点———并查集

并查集是一种用于管理元素所属集合的数据结构&#xff0c;实现为一个森林&#xff0c;其中每棵树表示一个集合&#xff0c;树中的节点表示对应集合中的元素。并查集支持两种操作&#xff1a; 合并&#xff08;Union&#xff09;&#xff1a;合并两个元素所属集合&#xff08;合…

828华为云征文 | 华为云Flexusx与Docker技术融合,打造个性化WizNote服务

前言 华为云Flexus X实例携手Docker技术&#xff0c;创新融合打造高效个性化WizNote服务。华为云Flexus X实例的柔性算力与Docker的容器化优势相结合&#xff0c;实现资源灵活配置与性能优化&#xff0c;助力企业轻松构建稳定、高效的云端笔记平台。828华为云企业上云节特惠来袭…

【JVM安装MySQL】

环境 > VMware Workstation Pro > CentOS 7 >Navicat Premium Lite > MobaXterm添加 MySQL Yum 仓库 根据操作系统在下载界面选取对应yum库进行下载 wget https://dev.mysql.com/get/mysql80-community-release-el7-9.noarch.rpm在文件下载界面安装 rpm -ivh mysq…

html+css+js网页设计 旅游 穷游10个页面

htmlcssjs网页设计 旅游 穷游10个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#xff…

苹果CMS插件:优化蜘蛛访问内容,提升百度收录率

确保蜘蛛抓取原始内容 专为苹果CMS设计的广告管理插件&#xff0c;能够智能识别搜索引擎蜘蛛与普通访客&#xff0c;确保蜘蛛访问时展示原始内容&#xff0c;从而提升被百度等搜索引擎收录的几率。 广告显示提升收益 对于普通访客&#xff0c;该插件则优先显示广告内容&#…

MySQL函数:数值函数

先附一张黑马程序员的听课截图 1. 向上取整函数CEIL(X) select CEIL(1.5); //这个也就是数学中的向上去整数&#xff0c;无需解释 2. 向下取整函数 FLOOR(X) select FLOOR(1.5); //同上&#xff0c;换成向下取整3. 求模运算 MOD(N,M) 求N / M的余数 select mod(3, 4) …

从入门到精通,带你探索适合新手的视频剪辑工具

用视频来分享生活已经变成越来越多人的一种习惯&#xff0c;很多时候视频并不能一镜到底&#xff0c;所以还需要一些的修改、剪辑操作&#xff0c;那么这次我将介绍几款视频剪辑工具&#xff0c;希望能够让你分享的道路更加通畅。 1.FOXIT视频剪辑 连接直达>>https://w…

Adobe Illustrator文字创建轮廓出现笔画缺失

问题如下&#xff1a; 左边为创建轮廓前&#xff0c;右边为创建轮廓后&#xff0c;可以发现笔画缺失了 解决办法&#xff1a; 办法一&#xff1a;放大字体 结果&#xff1a; 办法二&#xff1a;关闭GPU性能 结果&#xff1a;

Docker Registry API best practice 【Docker Registry API 最佳实践】

文章目录 1. 安装 docker2. 配置 docker4. 配置域名解析5. 部署 registry6. Registry API 管理7. 批量清理镜像8. 其他 &#x1f44b; 这篇文章内容&#xff1a;实现shell 脚本批量清理docker registry的镜像。 &#x1f514;&#xff1a;你可以在这里阅读&#xff1a;https:/…

【Binlog实战】:基于Spring监听Binlog日志

【Binlog实战】&#xff1a;基于Spring监听Binlog日志 binlog的三种模式 MySQL 的二进制日志&#xff08;binlog&#xff09;有三种不同的格式&#xff0c;通常被称为 binlog 模式。这三种模式分别是 Statement 模式、Row 模式和Mixed 模式。 Statement 模式&#xff1a; 在 …

Html css样式总结

1.Html css样式总结 1.1. 定位position 布局是html中非常重要的一部分&#xff0c;而定位在页面布局中也是使用频率很高的方法&#xff0c;本章节为定位在布局中的使用技巧和注意事项。   position定位有4个属性&#xff0c;分别是static(默认&#xff09;&#xff0c;absol…

Java音视频文件解析工具

文章目录 一 jave-all-deps二 具体用法2.1 添加依赖2.2 视频转音频2.3 视频格式转换2.4 获取视频时长 三 总结 小伙伴们知道&#xff0c;松哥平时录了蛮多视频课程&#xff0c;视频录完以后&#xff0c;就想整理一个视频文档出来&#xff0c;在整理视频文档的时候&#xff0c;就…

信息安全数学基础(17)Wilson定理

前言 Wilson定理&#xff08;Wilsons Theorem&#xff09;是数论中的一个基本定理&#xff0c;它揭示了素数与其阶乘之间的一个重要关系。 一、表述 对于任意素数p&#xff0c;有(p−1)!≡−1(modp)&#xff0c;其中(p−1)!表示p−1的阶乘&#xff0c;即123⋯(p−1)。 这个定理…

PM2.5粉尘传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理介绍 4.粉尘浓度转化关系 5.空气污染指数 三、程序设计 main.c文件 PM25.h文件 PM25.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 GP2Y1014AU是日本夏普公司开发的一款光学灰尘浓度检测传…

PyQt5 导入ui文件报错 AttributeError: type object ‘Qt‘ has no attribute

问题描述&#xff1a; 利用 PyQt5 编写可视化界面是较为普遍的做法&#xff0c;但是使用全新UI版本的 Pycharm 修改之前正常的UI文件时&#xff0c;在没有动其他代码的情况下发现出现以下报错 AttributeError: type object Qt has no attribute Qt::ContextMenuPolicy::Defaul…

Android Framework(六)WMS-窗口显示流程——窗口内容绘制与显示

文章目录 窗口显示流程明确目标 窗户内容绘制与显示流程窗口Surface的5种状态完整流程图 应用端处理finishDrawingWindow 的触发 system_service处理WindowState状态 -- COMMIT_DRAW_PENDING本次layout 流程简述applySurfaceChangesTransaction 方法概览READY_TO_SHOW和HAS_DRA…

基于springboot酒店管理系统

酒店管理系统 552酒店管理系统 摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;…