依赖注入的优缺点与最佳实践

这篇具有很好参考价值的文章主要介绍了依赖注入的优缺点与最佳实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 什么是依赖注入

依赖注入,全称Dependency Injection,简称DI。

在我们深入探讨之前,先来聊聊“依赖”和“注入”这两个比较术语的词。打个比方,你可以把“依赖”想象成电器设备的外接电线,而“注入”就像是把这根电线插到电源插座里,使用依赖注入就好比是你不需要知道电源插座在哪里,只需要知道有人会在你需要的时候为你插上插座,让电流连通,使设备工作。

在软件设计中,“依赖”指的是一个类需要调用的其他类或者服务,而“注入”则是指将这些所需的类或服务传递给需要它们的类的过程。使用“依赖注入”技术,我们可以在运行时将依赖关系传递给对象,而不是让对象自己去创建或查找它们需要的依赖。

如此,则软件中的组件可以在不同环境下重复使用,就像家里的电器可以随意在不同的插座上使用一样,不用担心它们的电源问题。“依赖注入”让我们的代码更加灵活,更容易维护和扩展。

依赖注入的优缺点与最佳实践,编程思想,控制反转,依赖注入

2 为什么需要依赖注入

2.1 为什么需要控制反转

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

控制反转(Inversion of Control,IOC)是一种设计原则,它让我们能够将程序的控制权从程序本身转移到外部容器或框架上。需要控制反转的具体理由主要包括如下几点:

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

想象一下,如果你是一位导演,你肯定希望能够专注于电影拍摄部分,而不是每天都忙于处理拍摄场地的预订、设备的采购这些琐事。这就是控制反转的魅力所在——它允许我们专注于核心业务逻辑,而将创建对象、管理生命周期等琐事交给框架去处理。

2.2 控制反转的需求举例:发消息

我们的业务需要向用户发送消息。最开始,我们可能使用短信来实现这一功能。随着技术的发展,我们可能改用微信消息,未来甚至可能使用一种全新的通讯方式——比如X信。

如果我们的代码直接依赖于某种特定的消息发送方式,每当需要改变时,我们都需要修改代码,这无疑是非常繁琐和容易出错的。控制反转让我们可以轻松应对这种变化,因为我们只需更换提供服务的对象即可。

依赖注入的优缺点与最佳实践,编程思想,控制反转,依赖注入

2.3 控制反转的其他实现:依赖查找(DL)

除了依赖注入,依赖查找(Dependency Lookup,DL)也是实现控制反转的一种方式。它的思路是在需要的时候,我们主动向一个管理容器询问或查找我们需要的依赖。这种方式比较传统,仍然依赖于容器的API,就像你需要知道每个插座在哪里,以及如何打开开关一样,这对于软件的解耦并不是最佳选择。

3 实现方式

3.1 使用接口

通过接口来抽象依赖是一个比较好的编程实践。在这种情况下,组件不会直接创建它们需要的依赖,而是通过引用接口来获得这些依赖的具体实现。这就像是制定一个规则,所有需要电力的设备都必须有一个标准的插头,这样它们就可以从任何一个标准插座获得电力。

注意使用接口不是必需的,你完全可以将一个不实现接口的类型实例注入到程序中。

3.2 基于set方法

在这种情况下,组件会提供一个公开的set方法,容器可以通过这个方法将依赖传递给组件。这就好比每个电器都有一个开关,当需要电力时,你只需打开开关即可。

3.3 基于构造函数

基于构造函数的注入是最直接的方式之一。当创建一个新的对象时,我们可以在构造函数中传递所有需要的依赖。这就像是买一个需要电池的设备时,店家直接给你装好电池,你拿回家就可以直接使用。

3.4 基于注解

在一些现代编程语言中,我们还可以使用注解(Annotations)来实现依赖注入。例如,在Java中,我们可以在构造函数、set方法、私有字段等元素上添加"@Autowired"注解,这样容器就会自动为我们注入依赖。

这就像是有一个自动插电系统,你只需要打开电器,它就会自动为你供电。

注意Spring中不再推荐使用"@Autowired"直接注解字段,因为这样写容易出Bug,还会让程序和依赖注入框架产生耦合。

4 开发语言支持

很多开发语言本身或者通过第三方框架提供了对依赖注入的支持,下边是一些介绍。

依赖注入的优缺点与最佳实践,编程思想,控制反转,依赖注入

4.1 C++

在C++标准库中没有对依赖注入的支持,但是社区有Google Fruit、Boost.DI、Hypodermic这样的框架,它们提供了依赖注入的能力。使用这些框架,C++开发者可以更容易地管理对象的生命周期和依赖关系。

4.2 Java

Java可能是依赖注入最为流行的领域之一,Spring Framework就是一个典型的例子。它提供了一整套依赖注入的解决方案,极大地简化了Java应用的开发。

4.3 .NET

在.NET世界中,ASP.NET Core默认就支持依赖注入,另外还可以选择Ninject、Autofac、Spring.NET等框架。这些框架使得.NET开发者可以轻松地实现依赖注入,使他们的应用程序更加模块化和可测试。

4.4 PHP

PHP也不例外,Phalcon和Laravel等框架提供了依赖注入的功能,使得PHP开发更加现代化,易于管理和维护。

---

这里为了让大家更好的感受,我们举一个Spring Boot的例子:

首先声明一个日志接口:

public interface ILogger {
    void log(String message);
}

然后创建一个实现类,我们使用 @Component 注解来标记 ConsoleLogger 作为一个可注入的组件。

import org.springframework.stereotype.Component;

@Component
public class ConsoleLogger implements ILogger {
    @Override
    public void log(String message) {
        System.out.println("Log: " + message);
    }
}

然后创建一个 Application 类,它使用 @Service 注解,并通过构造函数注入 ILogger 依赖。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class Application {
    private final ILogger logger;

    @Autowired
    public Application(ILogger logger) {
        this.logger = logger;
    }

    public void run() {
        logger.log("Application is running.");
    }
}

在 SpringApplicationMain 主类中注入 Application 类的实例并运行它。SpringApplicationMain 类实现了 CommandLineRunner 接口,当 Spring Boot 应用启动时,run 方法将被自动调用,然后会执行 application.run()。

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SpringApplicationMain implements CommandLineRunner {

    private final Application application;

    public SpringApplicationMain(Application application) {
        this.application = application;
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringApplicationMain.class, args);
    }

    @Override
    public void run(String... args) {
        application.run();
    }
}

优缺点

5.1 优点

  • 代码解耦:通过依赖注入,我们可以降低类与类之间的耦合度。这就好比你的手机、笔记本电脑和台式机可以使用同一个充电器一样方便。这种解耦让每个类更加专注于自己的职责,而不是担心如何与其他类协作。
  • 测试便利性:当你需要对某个类进行单元测试时,你可以轻松地替换它依赖的组件,使用模拟(Mock)对象来代替真实的实现。
  • 可维护性和可扩展性:随着业务的发展,需求会发生变化。依赖注入使得我们可以不改变现有代码的情况下,扩展或替换组件。这就像是为了应对不同的电压,你可以更换不同的电源适配器,而不是去修改电器本身。

5.2 缺点

  • 学习曲线:对于初学者来说,依赖注入可能会带来一定的学习挑战。理解控制反转和依赖注入的概念,以及如何在项目中正确使用它们,可能需要一定的时间和实践。
  • 过度设计:在一些简单的应用场景中,使用依赖注入可能会使得项目过度设计,增加不必要的复杂性。这就像是用一个巨大的电源站来给一盏台灯供电,虽然可行,但显然不是最优解。
  • 运行时性能:虽然现代依赖注入框架的性能已经非常优秀,但在一些性能敏感的场景下,依赖注入可能会引入轻微的性能开销。这种开销可以比喻为插座和电器之间连接的电线长度,虽然影响微乎其微,但在某些情况下需要考虑。

6 最佳实践

明确你的依赖:在使用依赖注入时,首先要明确你的类需要哪些外部依赖。这就像是在你搭建电路之前,需要知道哪些设备需要电源。

选择合适的注入方式:根据你的具体情况选择最合适的依赖注入方式,无论是setter注入还是构造器注入。这就像是选择合适的充电器插头,确保它与你的设备兼容。

避免过多的依赖:一个类不应该有太多的依赖,这会使得类变得难以管理和维护。想象一下,如果一个电器有太多的插头,使用起来就会变得非常麻烦。

使用依赖注入容器:使用依赖注入容器可以帮助你管理类的依赖关系,这就像是使用一个多功能的电源条,可以同时为多个设备供电。

结语

依赖注入作为一种设计模式,它旨在减少代码之间的耦合性,使代码更易于维护和测试。依赖注入的核心思想是将对象的创建与它们的使用分离开来。通过这种方式,依赖注入可以使代码更加灵活,更容易扩展和重用。随着软件行业的不断发展,依赖注入也在不断进化,它已经从一个编程技巧变成了一种软件设计的基本原则。

关注萤火架构,加速技术提升!文章来源地址https://www.toymoban.com/news/detail-816409.html

到了这里,关于依赖注入的优缺点与最佳实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JQ-6 Bootstrap入门到实战;Bootstrap的(优缺点、安装、响应式容器原理、网格系统、响应式工具类、Bootstrap组件);项目实践

    Bootstrap 读音 /ˈbu:tstræp/ ,是一个 非常受欢迎的前端框架 ,官方网站将其描述为。 最流行的 HTML、CSS 和 JS 框架,用于在 Web 上开发响应式、移动优先的项目。(v3.x) 响应式页面:页面布局会随着屏幕尺寸的变化而自动调整布局,作用是适配各个屏幕。 Bootstrap是功能强大、可扩

    2024年02月15日
    浏览(50)
  • springcloud 的优缺点:

    优点: 服务拆分粒度更细,有利于资源重复利用,有利于提高开发效率 可以更精准的制定优化服务方案,提高系统的可维护性 微服务架构采用去中心化思想,服务之间采用Restful等轻量级通讯,比ESB更轻量 适于互联网时代,产品迭代周期更短 缺点: 微服务过多,治理成本高

    2023年04月08日
    浏览(64)
  • SwiftUI的优缺点

    2019年WWDC大会上,苹果在压轴环节向大众宣布了基于Swift语言构建的全新UI框架——SwiftUI,开发者可通过它快速为所有的Apple平台创建美观、动态的应用程序。推荐大量使用struct代替类。 SwiftUI 就是⼀种声明式的构建界面的用户接口工具包。 SwiftUI使用声明式的语法构建UI,我们

    2024年02月13日
    浏览(54)
  • 量化交易的优缺点

       量化交易其实就像 《物种起源》 里的物种一样,随着计算机与 智能 机器人的发展 , 投资量化是时代 发展 的必然产物 。 所谓 能者为先 适 者生存,这是 放诸四海 皆为本 的 生存法则 。在 现代 科技欣欣向荣的发展 环境下 , 量化交易 所 表现出 的 种种 优势 , 使 全

    2023年04月08日
    浏览(102)
  • 48、MyBatis的优缺点

    基于 SOL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在 XML里,解除 sql 与程序代码的合,便于统一管理,提供 XML 标签,支持编写动态 SQL 语句,并可重用。 与JDBC 相比,减少了 50%以上的代码量,消除了JDBC 大量冗余的代码,不需要手动开

    2024年02月16日
    浏览(54)
  • SSM框架的优缺点

    SSM的优缺点 Mybatis 的优缺点 优点 1、与JDBC相比,减少了50%以上的代码量 2、最简单的持久化框架、小巧简单易学 3、SQL代码从程序代码中彻底分离出来,可重用 4、提供XML标签,支持编写动态SQL 5、提供映射标签,支持对象与数据库的ORM字段关系映射 缺点 1、SQL语句编写工作量

    2024年02月03日
    浏览(61)
  • 决策树的优缺点

    决策树优点 1. 易于理解和解释,因为树木可以画出来被看见 2. 需要很少的数据准备。其他很多算法通常都需要数据规范化,需要创建虚拟变量并删除空值等。但请注意, sklearn中的决策树模块不支持对缺失值的处理。 3. 使用树的成本(比如说,在预测数据的时候)是用于训

    2024年02月06日
    浏览(64)
  • ajax有哪些优缺点?

    Ajax是 异步的JavaScript和XML ,是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。 Ajax的优点有: 能够在不刷新页面的情况下进行数据的更新,提高了用户体验。 优化了浏览器和服务器之间的通信,减少了不必要的网络传输。 基于标准且被广泛支持,不需要

    2024年02月08日
    浏览(57)
  • CentOS 系统的优缺点

    CentOS (社区企业操作系统的缩写)是一个基于红帽企业 Linux (RHEL)的免费开源发行版, 旨在为服务器和工作站提供稳定、可靠和安全的平台。 不应将其与CentOS Stream 混淆,后者是即将发布的 RHEL 版本的上游开发平台。 CentOS Linux 源自 RedHat 发布的源代码,它是红帽停止支持其付

    2024年04月27日
    浏览(55)
  • RabbitMQ有什么优缺点

    为什么使用MQ?MQ的优点 简答 异步处理 - 相比于传统的串行、并行方式,提高了系统吞吐量。 应用解耦 - 系统间通过消息通信,不用关心其他系统的处理。 流量削锋 - 可以通过消息队列长度控制请求量;可以缓解短时间内的高并发请求。 日志处理 - 解决大量日志传输。 消息

    2024年02月11日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包