依赖注入的英文翻译是 Dependency Injection,缩写为 DI。对于这个概念,有一个非常形象的说法,那就是:依赖注入是一个标价 25 美元,实际上只值 5 美分的概念。也就是说,这个概念听起来很“高大上”,实际上,理解、应用起来非常简单。

那到底什么是依赖注入呢?我们用一句话来概括就是:不通过 new() 的方式在类内部创建依赖类对象,而是将依赖的类对象在外部创建好之后,通过构造函数、函数参数等方式传递(或注入)给类使用

我们还是通过一个例子来解释一下。在这个例子中,Notification 类负责消息推送,依赖 MessageSender 类实现推送商品促销、验证码等消息给用户。我们分别用依赖注入和非依赖注入两种方式来实现一下。具体的实现代码如下所示:


// 非依赖注入实现方式
public class Notification {private MessageSender messageSender;public Notification() {this.messageSender = new MessageSender(); //此处有点像hardcode}public void sendMessage(String cellphone, String message) {//...省略校验逻辑等...this.messageSender.send(cellphone, message);}
}public class MessageSender {public void send(String cellphone, String message) {//....}
}
// 使用Notification
Notification notification = new Notification();// 依赖注入的实现方式
public class Notification {private MessageSender messageSender;// 通过构造函数将messageSender传递进来public Notification(MessageSender messageSender) {this.messageSender = messageSender;}public void sendMessage(String cellphone, String message) {//...省略校验逻辑等...this.messageSender.send(cellphone, message);}
}
//使用Notification
MessageSender messageSender = new MessageSender();
Notification notification = new Notification(messageSender);

通过依赖注入的方式来将依赖的类对象传递进来,这样就提高了代码的扩展性,我们可以灵活地替换依赖的类。这一点在我们之前讲“开闭原则”的时候也提到过。当然,上面代码还有继续优化的空间,我们还可以把 MessageSender 定义成接口,基于接口而非实现编程。改造后的代码如下所示:


public class Notification {private MessageSender messageSender;public Notification(MessageSender messageSender) {this.messageSender = messageSender;}public void sendMessage(String cellphone, String message) {this.messageSender.send(cellphone, message);}
}public interface MessageSender {void send(String cellphone, String message);
}// 短信发送类
public class SmsSender implements MessageSender {@Overridepublic void send(String cellphone, String message) {//....}
}// 站内信发送类
public class InboxSender implements MessageSender {@Overridepublic void send(String cellphone, String message) {//....}
}//使用Notification
MessageSender messageSender = new SmsSender();
Notification notification = new Notification(messageSender);

实际上,你只需要掌握刚刚举的这个例子,就等于完全掌握了依赖注入。尽管依赖注入非常简单,但却非常有用,在后面的章节中,我们会讲到,它是编写可测试性代码最有效的手段。

思考

  • 为什么要使用依赖注入? – 降低耦合性

总结

  • 依赖注入就是在外部创建好类,然后通过构造函数或者函数参数,传递给需要的类

参考

19 | 理论五:控制反转、依赖反转、依赖注入,这三者有何区别和联系?

依赖注入(DI)入门相关推荐

  1. 框架依赖注入和普通依赖注入_依赖注入快速入门:它是什么,以及何时使用它...

    框架依赖注入和普通依赖注入 by Bhavya Karia 通过Bhavya Karia 介绍 (Introduction) In software engineering, dependency i ...

  2. 依赖注入(DI)和Ninject,Ninject

    我们所需要的是,在一个类内部,不通过创建对象的实例而能够获得某个实现了公开接口的对象的引用.这种"需要",就称为DI(依赖注入,Dependency Injection),和所谓的 ...

  3. 依赖倒置(DIP),控制反转(IoC)与依赖注入(DI)

    DIP,IoC与DI概念解析 依赖倒置 DIP(Dependency Inversion Principle) DIP的两大原则: 1.高层模块不应该依赖于低层模块,二者都应该依赖于抽象. 2.抽象不 ...

  4. 控制反转(Ioc)和依赖注入(DI)

    控制反转IOC, 全称 "Inversion of Control".依赖注入DI, 全称 "Dependency Injection". 面向的问题:软件开发 ...

  5. 控制反转IOC与依赖注入DI

    为什么80%的码农都做不了架构师?>>>    1. IoC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最 ...

  6. PHP依赖注入(DI)和控制反转(IoC)详解

    这篇文章主要介绍了PHP依赖注入(DI)和控制反转(IoC)的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程 ...

  7. Java依赖注入 - DI设计模式示例教程

    Java依赖注入 - DI设计模式示例教程 Java依赖注入 设计模式允许我们删除硬编码的依赖项,并使我们的应用程序松散耦合,可扩展和可维护.我们可以在java中实现依赖注入,以将依赖项解析从编译时移 ...

  8. [Android]使用Dagger 2依赖注入 - DI介绍(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5092083.html 使用Dagger 2依赖注入 - DI介 ...

  9. ioc控制反转_深入理解依赖注入(DI)和控制反转(IOC)

    转载本文务必须注明出处.微信号(Yemeir_com).以及添加原文链接. 为什么要使用依赖注入 使用依赖注入(DI)可以使控制者与抽象实现者松耦合,便于单元测试.通过控制反转(IOC)的设计原理来减 ...

  10. 依赖注入(di)模式_Java依赖注入– DI设计模式示例教程

    依赖注入(di)模式 Java Dependency Injection design pattern allows us to remove the hard-coded dependencies ...

最新文章

  1. mysql 5.7 驱动_这些 MySQL 调优配置,你都知道吗?
  2. java生产问题快速定位_生产环境如何快速跟踪、分析、定位问题-Java
  3. python 行列式计算
  4. Mac中MacPorts安装和使用 MacPorts简介
  5. Careercup - Google面试题 - 4877486110277632
  6. windows传真和扫描由于不能访问您的文档_扫描识别工具Dynamic Web TWAIN全年最低价来了!错过再等一年...
  7. 蓝桥杯入门训练圆的面积c语言,蓝桥杯-入门训练-圆的面积
  8. Kotlin入门(31)JSON字符串的解析
  9. 图片随鼠标滚动而任意浮动
  10. 学习SharePoint你需要什么?
  11. [bzoj1031][JSOI2007]字符加密Cipher
  12. eo是什么?一份没有满分的试题
  13. 如何用计算机记英语词汇,计算机英语词汇学习方法
  14. 操作系统——进程间通信
  15. 【解决问题】WindowsXXX端口已被占用:以 1080端口已被占用 为例
  16. 如何评价《守望先锋》架构设计?
  17. matlab 代码 经典例题,MATLAB程序设计及经典例题解析3
  18. 关于Ubuntu双击打不开文件夹的解决方案
  19. 【图文动画详解原理系列】1.MySQL 索引原理详解
  20. Macbook无法开机?如何尝试自救

热门文章

  1. VALSE学习(十八):复杂视频的深度高效分析与理解方法
  2. VALSE学习(四):注意力机制-Attention Network
  3. 威纶通宏开机后使用初始化宏指令_你按下电脑开机键后,电脑都干了些什么?...
  4. 阿里云ECS服务器怎么安装宝塔面板?
  5. python删除链表重复节点_LeetCode-python 82.删除排序链表中的重复元素 II
  6. vue3.0 vuex 全局变量 存储更改
  7. mysql存储php数组_mysql数据库存储PHP数组、对象的方法
  8. python图层_Python叠加矩形框图层2种方法及效果
  9. go 类型断言_深入理解Go的interface内部执行原理
  10. vim 安装_vim实战:插件安装(Vundle,NerdTree)