设计模式-依赖注入

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

一个类依赖于另一个类或者服务来完成某些功能。然而,硬编码的依赖关系会导致代码耦合度过高,难以测试和维护。为了解决这个问题,我们引入了一种设计模式——依赖注入(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,一经查实,立即删除!

相关文章

探索学习Python的最佳开发环境和编辑器

Python&#xff0c;作为目前最受欢迎的编程语言之一&#xff0c;因其简洁明了的语法和强大的功能性而备受开发者喜爱。无论是数据科学、机器学习、Web开发还是自动化脚本&#xff0c;Python都有着广泛的应用。选择合适的开发环境和编辑器对于提高编程效率和学习体验至关重要。 …

ArcGIS Pro SDK (十六)公共设施网络 1 网络管理

ArcGIS Pro SDK (十六)公共设施网络 1 网络管理 文章目录 ArcGIS Pro SDK (十六)公共设施网络 1 网络管理1 获取公共设施网络1.1 从表中获取公共设施网络1.2 从图层获取公共设施网络2 元素2.1 从元素中获取行3 编辑关联3.1 创建公共设施网络关联3.2 在单个编辑操作中创建公…

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…

Web 创建设计

Web 创建设计 Web 创建设计是一个涉及多个方面的过程,它包括网站的视觉设计、用户界面设计、用户体验设计、前端开发以及后端开发等。本文将详细介绍这些方面,并探讨如何创建一个既美观又实用的网站。 1. 视觉设计 视觉设计是网站创建设计的第一步,它决定了网站的外观和感…

Explain执行计划

Explain执行计划 explain可以帮助开发人员分析SQL问题&#xff0c;explain用于显示MySQL如何使用SQL执行计划&#xff0c;可以帮助开发人员写出更优化的查询语句。使用方法就是在查询语句前加上explain关键字。 执行添加上explain关键字的语句可以看到一个列表&#xff1a; 其…

算法知识点———并查集

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

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

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

如何在创建数据库时预定义表结构:以图书管理系统的例子说明

示例 假设要为一个图书管理系统创建数据库&#xff0c;可以预先定义如下的表结构&#xff1a; 书籍表&#xff08;Books&#xff09; book_id (INT, 主键)title (VARCHAR)author (VARCHAR)publication_year (YEAR) 作者表&#xff08;Authors&#xff09; author_id (INT, 主键…

项目实战 (11)---搜索进度

目录 背景 相关技术 需要解决的问题 查询进度实时展示 描述 代码 python 后端 html JS 运行效果 查询逻辑结合 描述 代码 运行效果 总结与问题 背景 通过前面1-10,视频搜索系统的前后端及视频录入功能已经可以正常使用。但是我们清楚随着视频量的增加及客户搜…

html知识点框架

一、HTML基础 HTML简介 HTML是一种超文本标记语言&#xff0c;用于创建网页和网页应用。HTML5是公认的下一代Web语言&#xff0c;极大地提升了Web在富媒体、富内容和富应用等方面的能力。HTML基本结构 基本的HTML文档结构包括<!DOCTYPE html>, <html>, <head&g…

【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; 在 …