依赖注入学习

1.介绍

依赖注入(Dependency Injection, DI)是一种软件设计模式,用于实现类与其依赖项之间的解耦。它的核心思想是,将类所依赖的对象通过外部注入的方式传递给它,而不是在类内部自行创建依赖对象。通过这种方式,代码变得更加灵活、可维护,并且有助于提高可测试性。

在面向对象编程中,类通常依赖于其他类来完成工作。例如,类 A 可能需要调用类 B 来执行一些功能。如果类 A 在内部直接创建类 B 的实例,那么这两者之间便紧密耦合,难以在不修改类 A 的情况下替换或测试类 B。

依赖注入 通过将依赖项(如类 B)从外部传递给类 A,可以解除两者之间的直接依赖。类 A 不再负责创建依赖项,而是依赖于外部提供的依赖项。

2.常见方式

2.1 构造函数注入具体类

// 具体的类
class Service {
public:void execute() {std::cout << "Executing service..." << std::endl;}
};class Client {
private:Service* service;
public:// 通过构造函数注入依赖项Client(Service* s) : service(s) {}void doWork() {service->execute();}
};int main() {Service s;Client c(&s);  // 注入依赖c.doWork();    // 使用注入的依赖return 0;
}

2.2 构造函数注入抽象类

// 抽象类,接口。
class IService {
public:virtual void execute() = 0;
};class Service : public IService {
public:void execute() override {std::cout << "Executing service..." << std::endl;}
};class Client {
private:IService* service; // 抽象类,
public:void setService(IService* s) {service = s;}void doWork() {service->execute();}
};int main() {Service s;Client c;c.setService(&s);  // 注入实现接口的依赖c.doWork();return 0;
}

2.3 set函数注入

class Client {
private:Service* service;
public:void setService(Service* s) {service = s;}void doWork() {service->execute();}
};int main() {Service s;Client c;c.setService(&s);  // 通过 setter 方法注入依赖c.doWork();return 0;
}

允许依赖在对象创建之后设置。

3.优点

  • 解耦:通过依赖注入,类不再负责创建依赖项,而是依赖外部传递的对象,这大大降低了类之间的耦合性。松耦合,loose coupling。

  • 可测试性:在测试时,可以方便地替换依赖项(如使用 mock 对象),从而更容易进行单元测试。

https://juejin.cn/post/7321967859242958857

依赖注入其实是控制反转(IOC)的一种实现方式。

需要控制反转的具体理由主要包括如下几点:

  • 实际只需要对象提供的服务,不需要关心对象从何而来。
  • 时空转变时,可能需要不同的对象来提供类似的服务,比如对于数据库操作服务,单元测试时需要模拟操作,而实际运行时需要真实操作。
  • 拥有对象的控制权时,需要不断的改造自己,麻烦且容易出问题。比如依赖项的构造函数变化、具体实现的更改等。
  • 将对象创建的控制权交出去,让外部场景来提供合适的服务对象。这可以让程序更容易组件化,更方便组合。

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

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

相关文章

Mac M2基于MySQL 8.4.3搭建(伪)主从集群

前置准备工作 安装MySQL 8.4.3 参考博主之前的文档&#xff0c;在本地Mac安装好MySQL&#xff1a;Mac M2 Pro安装MySQL 8.4.3安装目录&#xff1a;/usr/local/mysql&#xff0c;安装好的MySQL都处于运行状态&#xff0c;需要先停止MySQL服务最快的方式&#xff1a;系统设置 …

Ubuntu平台虚拟机软件学习笔记

Ubuntu平台上常见虚拟机软件 VirtualBox [Download]KVM/QEMU 1. VirtualBox 1.1 查看安装版本 VBoxManage -V2. KVM/QEMU KVM: Kernel-based Virtual Machine QEMU: Quick EMUlator 通义千问&#xff1a; virt-manager 既不是QEMU也不是KVM&#xff0c;而是用于管理和创建…

事务的回滚与失效行为

创建一张测试表 AccountMapper public interface AccountMapper {Update("update account set balance #{balance} where username #{username}")int updateUserBalance(Param("username") String username, Param("balance") Integer bal…

【C语言】_字符数组与常量字符串

目录 1. 常量字符串的不可变性 2. 关于常量字符串的打印 3. 关于字符数组与常量字符串的内存分布 1. 常量字符串的不可变性 char arr[10] "abcdef";// 字符数组char* p2 arr;char* p3 "abcdef"; // 常量字符串 尝试对常量字符串进行修改&#xff…

【GUI-pyqt5】QCommandLinkButton类

1. 描述 命令链接的Windows Vista引入的新控件他的用途类似于单选按钮的用途&#xff0c;因为他用于在一组互斥选项之间进行选择命令链接按钮不应单独使用&#xff0c;而应作为向导和对话框中单选按钮替代选项外观通常类似于平面按钮的外观&#xff0c;但除了普通按钮文本外&a…

69.基于SpringBoot + Vue实现的前后端分离-家乡特色推荐系统(项目 + 论文PPT)

项目介绍 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括家乡特色推荐的网络应用&#xff0c;在外国家乡特色推荐系统已经是很普遍的方式&#xff0c;不过国内的管理网站可能还处于起步阶段。家乡特色推荐系统采用java技术&…

HCIE-day10-ISIS

ISIS ISIS&#xff08;Intermediate System-to-Intermediate System&#xff09;中间系统到中间系统&#xff0c;属于IGP&#xff08;内部网关协议&#xff09;&#xff1b;是一种链路状态协议&#xff0c;使用最短路径优先SPF算法进行路由计算&#xff0c;与ospf协议有很多相…

图像处理|膨胀操作

在图像处理领域&#xff0c;形态学操作是一种基于图像形状的操作&#xff0c;用于分析和处理图像中对象的几何结构。**膨胀操作&#xff08;Dilation&#xff09;**是形态学操作的一种&#xff0c;它能够扩展图像中白色区域&#xff08;前景&#xff09;或减少黑色区域&#xf…

Solidity合约编写(三)

解决问题&#xff1a; 在 Solidity 合约中使用 Chainlink 获取 ETH/USD 的价格&#xff08;汇率&#xff09;&#xff0c;需要使用 Chainlink 的 AggregatorV3Interface 接口。以下是一个样板代码&#xff0c;展示了如何在测试链&#xff08;如 Goerli 或 Sepolia&#xff09;…

[Git] git cherry-pick

git cherry-pick -m1 a498a7a 是一个 Git 命令&#xff0c;用于将一个特定的合并提交&#xff08;merge commit&#xff09;中的更改应用到当前分支。这对于想要从合并提交中提取特定更改并将其应用于另一个分支时非常有用。 参数解释 cherry-pick&#xff1a;这是 Git 中的一…

【机器学习】量子机器学习:当量子计算遇上人工智能,颠覆即将来临?

我的个人主页 我的领域&#xff1a;人工智能篇&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;&#x1f44d;点赞 收藏❤ 在当今科技飞速发展的时代&#xff0c;量子计算与人工智能宛如两颗璀璨的星辰&#xff0c;各自在不同的苍穹闪耀&#xff0c;正以前…

Sprint Boot教程之五十:Spring Boot JpaRepository 示例

Spring Boot JpaRepository 示例 Spring Boot建立在 Spring 之上&#xff0c;包含 Spring 的所有功能。由于其快速的生产就绪环境&#xff0c;使开发人员能够直接专注于逻辑&#xff0c;而不必费力配置和设置&#xff0c;因此如今它正成为开发人员的最爱。Spring Boot 是一个基…

腾讯云AI代码助手编程挑战赛-桌面壁纸随机更换

作品简介 用于更换壁纸缓缓心情&#xff0c;或者选择困难症&#xff0c;每一个图片都想用来做壁纸&#xff0c;并且节约了手工时间&#xff0c;所以根据这个需求来创建的这款应用工具&#xff0c;使用的是腾讯云AI代码助手来生成的所有代码&#xff0c;使用方便&#xff0c;快…

Redis 性能优化:利用 MGET 和 Pipeline 提升效率

概述 在现代应用程序中&#xff0c;Redis 被广泛用作缓存和数据存储解决方案。为了充分发挥 Redis 的高性能特性&#xff0c;了解并有效利用其命令和技术是至关重要的。在这篇博客中&#xff0c;我们将探讨如何通过 MGET 和 Pipeline 技术来优化 Redis 的性能&#xff0c;并讨…

说说你对作用域链的理解

一、作用域 作用域&#xff0c;即变量&#xff08;变量作用域又称上下文&#xff09;和函数生效&#xff08;能被访问&#xff09;的区域或集合 换句话说&#xff0c;作用域决定了代码区块中变量和其他资源的可见性 举个例子 function myFunction() {let inVariable "…

SpringBootWeb 登录认证(day12)

登录功能 基本信息 请求参数 参数格式&#xff1a;application/json 请求数据样例&#xff1a; 响应数据 参数格式&#xff1a;application/json 响应数据样例&#xff1a; Slf4j RestController public class LoginController {Autowiredpriva…

java内存区域 - 栈

目录 java内存区域 - 栈1. Java虚拟机栈的组成2. 栈帧中的详细内容2.1 局部变量表2.2 操作数栈2.3 动态链接2.4 方法返回地址2.5 附加信息 3. JVM栈的生命周期4. 示例解析 - 运行时的栈帧分布5. 栈中的异常6.栈配置7.本地方法栈 java内存区域 - 栈 在JDK11中&#xff0c;JVM栈…

ASP.NET Core 实现微服务 - Consul 配置中心

这一次我们继续介绍微服务相关组件配置中心的使用方法。本来打算介绍下携程开源的重型配置中心框架 apollo 但是体系实在是太过于庞大&#xff0c;还是让我爱不起来。因为前面我们已经介绍了使用Consul 做为服务注册发现的组件 &#xff0c;那么干脆继续使用 Consul 来作为配置…

【HarmonyOS】纯血鸿蒙真实项目开发---经验总结贴

项目场景&#xff1a; 将已有的Web网页接入到原生App。 涉及到一些网页回退、webviewController执行时机报错1710000001、位置定位数据获取、拉起呼叫页面、系统分享能力使用等。 问题描述 我们在选项卡组件中&#xff0c;在每个TabContent内容页中使用web组件加载网页。 在…

Maven 仓库的分类

Maven 是一个广泛使用的项目构建和依赖管理工具&#xff0c;在 Java 开发生态中占据重要地位。作为 Maven 的核心概念之一&#xff0c;仓库&#xff08;Repository&#xff09;扮演着至关重要的角色&#xff0c;用于存储项目的依赖、插件以及构建所需的各种资源。 了解 Maven 仓…