0x00.前言

当我们研究一些晦涩的源码,上网查阅资料的时候,映入眼帘的总有这么些名词:DIP、IOC、DI、DL、IOC容器这些专业名词。如果不懂这些名词背后的含义,我们内心有可能是这样的:

0x01.小例子

/**
* 餐厅类
*/
public class Restaurant { //后台收银系统
private WeChatPay pay = new WeChatPay(); //收款操作
public void transact(double money) {
pay.receiveMoney(money);
}
}
import java.util.Date;

/**
* 微信
*/
public class WeChatPay {
public void receiveMoney(double money) {
System.out.println(new Date() + ",已用微信收款:" + money + "元");
}
}

这时候Restaurant类就依赖于WeChatPay,两个类产生依赖

0x02.DIP

DIP的英文名:Dependency Inversion Principle,中文名:依赖倒转原则

定义:

  • High-level modules should not depend on low-level modules. Both should depend on abstractions

  • Abstractions should not depend on details. Details should depend on abstractions

理解:

  • 高层模块不应该直接依赖于底层模块的具体实现,而应该依赖于底层的抽象。换言之,模块间的依赖是通过抽象发生,实现类之间的不发生直接依赖关系,其依赖关系是通过接口或抽象类产生的

  • 面向接口编程

它仅仅是面向对象软件设计的一种原则。它仅仅告诉你两个模块之间如何协调依赖关系,但是并没有告诉你如何做!

举个例子

我们经常所说的三层架构(UI、BLL、DAL)

图二的版本,就是高层模块依赖于低层模块的抽象,就好像依赖“倒置”。这样可以使得整体的架构更加的稳定,灵活,及自如的面对需求的变化。

0x03.IOC

  • IOC的英文名:Inversion Of Control ,中文名:控制反转
  • IOC基于DIP原则上的实现的是一种软件设计模式,它告诉你应该如何做,来解除相互依赖模块的耦合。它为相互依赖的组件提供抽象,将依赖对象的获得交给第三方来控制,即依赖对象不在被依赖的类中直接通过new来获取。
  • IOC的实现的方式一般有两种,依赖注入和依赖查找。一般DI使用的比较多

0x04.DI

  • DI的英文名:Dependency Injection,中文名称:依赖注入。
  • DI就是将依赖对象的创建和绑定转移到被依赖对象类的外部来实现。它提供是一种机制,将需要依赖(低层模块)对象的引用传递给被依赖(高层模块)对象。

DI注入有三种方式

  • 构造函数注入
  • 属性注入
  • 接口注入

Demo讲解

/**
* di Ipay 接口
*/
public interface IPay {
void receiveMoney(double money);
}
/**
* 重构后的微信支付
*/
public class WebChatPay implements IPay {
public void receiveMoney(double money) {
Date now = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(format.format(now) + ",已用重构后的微信收款:" + money + "元");
}
}
/**
* 重构后的餐厅类构造器注入
*/
public class Restaurant { private IPay _pay; public Restaurant(IPay pay) {
this._pay = pay;
} //收款操作
public void transact(double money) {
_pay.receiveMoney(money);
}
}

0x01.构造器注入

System.out.println("==========通过构造函数注入开始==============");
IPay pay = new WebChatPay();//在外部创建依赖对象
Restaurant restaurant = new Restaurant(pay);
restaurant.transact(10);
System.out.println("==========通过构造函数注入结束==============");

这时候我们就看到Restaurant将依赖的WeChatPay对象的创建和绑定转移到Restaurant类外部来实现了。这样就解除了Restaurant类与WeChatPay类的耦合关系。如果将支付方式改成Alipay,只需要定义一个Alipay类,然后在外部重新绑定依赖。不需要修改Restaurant类。

0x02.属性注入

System.out.println("==========通过属性注入开始==============");
IPay paySetter = new WebChatPay();
RestaurantBySetter restaurantSetter = new RestaurantBySetter();
restaurantSetter.setPay(paySetter);
restaurantSetter.transact(10);
System.out.println("==========通过属性注入结束==============");

0x03.接口注入

System.out.println("==========通过接口注入开始==============");
IPay payInterface = new WebChatPay();
RestaurantByInterface restaurantInterface = new RestaurantByInterface();
restaurantInterface.extraInstance(payInterface);
restaurantInterface.transact(10);
System.out.println("==========通过接口注入结束==============");

0x05.IOC容器

DI框架,用来自动创建、维护依赖对象,并管理其生命周期。

常使用的IOC容器有:

Net:Ninject、Spring.NET、Unity、Autofac等

Java:Spring等

0x06.总结

IOC带来好处:

  • 降低了各个组件之间的耦合性,增强了内聚性。
  • 大中型项目,团队分工明确,职责明确,便于测试
  • 使得模块具有热插拔特性,增加了模块的复用性

剖析DI的更多相关文章

  1. ASP.NET MVC不可或缺的部分——DI(IOC)容器及控制器重构的剖析(DI的实现原理)

    IoC框架最本质的东西:反射或者EMIT来实例化对象.然后我们可以加上缓存,或者一些策略来控制对象的生命周期,比如是否是单例对象还是每次都生成一个新的对象. DI实现其实很简单,首先设计类来实现接口, ...

  2. 从EFCore上下文的使用到深入剖析DI的生命周期最后实现自动属性注入

    故事背景 最近在把自己的一个老项目从Framework迁移到.Net Core 3.0,数据访问这块选择的是EFCore+Mysql.使用EF的话不可避免要和DbContext打交道,在Core中的常 ...

  3. Asp.Net Core下的开源任务调度平台ScheduleMaster

    从何说起 2017年初的时候,由于当时项目需要做了一个乞丐版定时调度系统,那时候只在单机上实现了核心的调度功能.做这个玩意之前也调研了社区中开源的解决方案,找了几个实地部署试跑了一下,其实都很不错.但 ...

  4. ASP.NET MVC不可或缺的部分——DI(IOC)容器及控制器重构的剖析

    ASP.NET MVC不可或缺的部分——DI(IOC)容器及控制器重构的剖析   IoC框架最本质的东西:反射或者EMIT来实例化对象.然后我们可以加上缓存,或者一些策略来控制对象的生命周期,比如是否 ...

  5. Core官方DI剖析(1)--ServiceProvider类和ServiceCollection类

    前段时间看了蒋老师的Core文章,对于DI那一块感觉挺有意思,然后就看了一下Core官方DI的源码,这也算是第一个看得懂大部分源码的框架,虽然官方DI相对来说特别简单, 官方DI相对于其它框架(例如 ...

  6. ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件)

    ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件) Startup Class 1.Startup Constructor(构造函数) 2.Configure ...

  7. 深入剖析 redis AOF 持久化策略

    本篇主要讲的是 AOF 持久化,了解 AOF 的数据组织方式和运作机制.redis 主要在 aof.c 中实现 AOF 的操作. 数据结构 rio redis AOF 持久化同样借助了 struct ...

  8. 控制反转IOC与依赖注入DI【转】

    转自:http://my.oschina.net/1pei/blog/492601 一直对控制反转.依赖注入不太明白,看到这篇文章感觉有点懂了,介绍的很详细. 1. IoC理论的背景我们都知道,在采用 ...

  9. WCF技术剖析之七:如何实现WCF与EnterLib PIAB、Unity之间的集成

    原文:WCF技术剖析之七:如何实现WCF与EnterLib PIAB.Unity之间的集成 在这之前,我写过深入介绍MS EnterLib PIAB的文章(参阅<MS Enterprise Li ...

随机推荐

  1. 20165322 预备作业3 Linux安装及学习

    Linux安装及学习 安装部分 由于是第一次接触虚拟机知识,之前也没什么了解,我选择完全按照老师教程里的安装vbox虚拟机. 虚拟机安装的过程很顺利,不做详细讲解. 出现的问题 在启动我新建的虚拟电脑 ...

  2. 【转】不错的linux下通用的java程序启动脚本

    虽然写起动shell的频率非常不高...但是每次要写都要对付一大堆的jar文件路径,新加jar包也必须要修改起动shell. 在网上找到一个挺好的通用shell脚本. 只需要修改一些配置变量,就可以用 ...

  3. 二.Mybatis 增删改查

    Student.java package com.pojo; import java.util.Date; public class Student { int stuid; String stuNa ...

  4. P1272

    P1272 重建道路 题目描述 一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟 ...

  5. Android学习笔记_69_android 支付宝之网页支付和快捷支付

    参考资料: https://b.alipay.com/order/productDetail.htm?productId=2013080604609654 https://b.alipay.com/o ...

  6. static函数

    C语言中使用静态函数的好处:      静态函数会被自动分配在一个一直使用的存储区,直到退出应用程序实例,避免了调用函数时压栈出栈,速度快很多.       关键字“static”,译成中文就是“静态 ...

  7. linux系统命令与常识

    之前短期学过linux,用到时才发现已经忘得一干二净了. 现在对学过的和了解到的做一个总结: 先明确一些使用工具: winscp : WinSCP是一个Windows环境下使用SSH的开源图形化SFT ...

  8. docker官方文档翻译3

    转载请标明出处: https://blog.csdn.net/forezp/article/details/80171723 本文出自方志朋的博客 第三部分: 服务 准备工作 安装Docker 1.1 ...

  9. Aaliyun Linux 64 安装jdk+mysql+tomcat

    参考: http://www.blogjava.net/amigoxie/archive/2013/02/22/395605.html http://bbs.aliyun.com/read/17704 ...

  10. Plupload使用API

    Plupload有以下功能和特点: 1.拥有多种上传方式:HTML5.flash.silverlight以及传统的<input type=”file” />.Plupload会自动侦测当前 ...