本篇和大家一起学习IoC和DI即控制反转和依赖注入。

当然听上去这词语非常的专业,真不知道是怎么组出来的,看上去难归看上去难,但稍微理解一下也就这么回事了。

首先我们要明白IoC/DI干嘛用的,不然别人问“你知道IoC/DI吗?”,“知道啊!”,“那干嘛用的?”,呵呵,就郁闷了,其实IoC/DI的作用就两个字——解耦,说一千道一万,还是离不开这两个字。所以,IoC/DI的作用就是解耦。

至于为什么要解耦,解耦在面向对象开发中的重要性在这里就不做细说了。

下面我们来认识一下它们的真面目吧!

要理解IoC/DI两个概念,就必须搞清楚如下问题:

  • 参与者都有谁?
  • 依赖:谁依赖于谁?为什么需要依赖?
  • 注入:谁注入谁?到底注入了什么?
  • 控制反转:谁控制谁?控制什么?为什么叫反转?有没有正向呢?正向又是什么?
  • 依赖注入和控制反转是同一概念吗?

下面来简要回答一下上述问题,把这些问题搞明白了,也就明白了IoC/DI。

  1. 参与者都有谁:一般有三方参与,一个是某个对象,一个是IoC/DI容器,还有就是某个对象的外部资源。

    注:某个对象指任意一个普通的对象,IoC/DI容器简单说就是用来实现IoC/DI功能的一个框架程序,比如现在有许多IoC/DI框架(Unity、Spring.NET、Autofac),对象的外部资源指对象需要的,但是从对象外部获取的,都统称资源,比如对象需要其他对象。

  1. 谁依赖于谁:当然是某个对象依赖于IoC/DI容器
  2. 为什么需要依赖:因为对象需要IoC/DI的容器来提供对象需要的外部资源。
  3. 谁注入谁:IoC/DI的容器注入某个对象
  4. 到底注入了什么:就是注入某个对象所需要的外部资源,说完整点就是IoC/DI的容器将某个对象所需要的外部资源注入了该对象。
  5. 谁控制谁:IoC/DI的容器来控制对象
  6. 控制什么:主要是控制对象实例的创建
  7. 为什么叫反转:反转是相对与正向而言的。
  8. 正向又是什么:通常情况下的应用程序,如果在A里使用C,一般我们会直接创建C的对象,也就是说,在A类中主动获取所需要的外部资源,这种情况被成为正向的,那什么是反向呢?就是A类不再主动去获取C,而是被动等待,等待IoC/DI的容器获取一个C的实例,然后反向地注入到A类中。

先看没有IoC/DI的时候,常规A类使用C的示意图

当有了IoC/DI的容器后,A类不再主动去创建C了,而是被动等待,等待IoC/DI的容器获取C的实例,然后反向注入到A类中。

依赖注入和控制反转是同一概念吗?

根据上面讲述,依赖注入和控制反转是对同一件事情的不同描述。依赖注入使用应用程序的角度去描述,我们可以把依赖注入描述的完整点:应用程序依赖容器创建并注入它所需要的外部资源。控制反转是从容器的角度去描述的,描述的完整点就是:容器控制应用程序,由容器反向的向应用程序注入其所需要的外部资源。

好了,通过上述学习,大家都应该对IoC/DI有了基本了解,下面我们再来正式认识下依赖注入和控制反转。

依赖注入中,依赖关系就像被注入的液体,我们可以在任何时候将依赖关系注入到模块中,而不只局限于编译是绑定。这种依赖关系是通过注入的方式完成的,就意味着我们可以随时更新,因为注入的液体与模块本身并无直接关联,举个不恰当的比喻,我们难道天生就要和针筒打交道吗?

实现依赖注入的前提是面向接口编程,辅助的技术可以使用反射技术。

MF.将依赖注入的形式分为三种:构造函数注入、设置方法注入和接口注入。

接口注入是通过定义接口约束的方式实现依赖注入,会给容器带来设计的限制。

而构造函数注入与设置方法(可以是属性)注入则是使用类的构造函数以及自定义的setter方法或属性进行依赖注入(关于这两点,可以参考第一篇《设计模式之UML类图的常见关系(一)》中的聚合和组合关系)。

在这里我们也把第一篇聚合和组合关系类图拿到了。

下面这个是使用Setter方法/属性实现依赖注入的。说白了就是定义一个Setter方法/属性,在该方法/属性内将对象关联起来。

下面这个是构造函数的依赖注入,就是将Setter方法/属性换成了构造函数,但是请仔细看看两幅图片的代码和注入,什么时候使用Setter方法/属性注入,什么时候使用构造函数注入,当时在开发过程中,通常是使用构造函数进行依赖注入的。

还有一个就是接口注入。

这是我认为最不够优雅的一种依赖注入方式。要实现接口注入,首先ServiceProvider要给出一个接口定义:

  1. public interface InjectFinder {
  2. void injectFinder(MovieFinder finder);
  3. }

接下来,ServiceUser必须实现这个接口:

  1. class MovieLister: InjectFinder
  2. {
  3. private MovieFinder finder;
  4. public void injectFinder(MovieFinder finder) {
  5. this.finder = finder;
  6. }
  7. }

为什么现在介绍IoC/DI呢?

想想,前面我们已经学习了三种工厂,那能不能将工厂和IoC/DI联系起来呢?好了,下面就自己想想!

小结:IoC/DI对编程带来的最大改变不是在代码上,而是在思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动了,被动的等待IoC/DI容器来创建并注入它所需要的资源。

设计模式之初识IoC/DI(六)的更多相关文章

  1. 设计模式——从工厂方法模式到 IOC/DI思想

    回顾简单工厂 回顾:从接口的角度去理解简单工厂模式 前面说到了简单工厂的本质是选择实现,说白了是由一个专门的类去负责生产我们所需要的对象,从而将对象的创建从代码中剥离出来,实现松耦合.我们来看一个例子 ...

  2. PHP程序员如何理解IoC/DI(转)

    php - Dependency Injection依赖注入 和 自动加载 各自的优缺点 ioc/di和自动加载时两回事. ioc/di 让代码由创建对象改为注入对象,是一种编程思想,而自动加载,只是 ...

  3. 关于依赖注入IOC/DI的感想

    之前一直不明白依赖注入有什么好处,甚至觉得它是鸡肋,现在想想,当时真是可笑. 这个想法正如同说接口是没有用处一样. 当整个项目非常庞大,各个方法之间的调用非常复杂,那么,可以想象一下,假设说没有任何的 ...

  4. 如何理解IoC/DI

    IoC:Inversion of Control,控制反转DI:Dependency Injection,依赖注入 要理解上面两个概念,就必须搞清楚如下的问题: 参与者都有谁?依赖:谁依赖于谁?为什么 ...

  5. IOC DI 专题

    IoC:Inversion of Control,控制反转DI:Dependency Injection,依赖注入 要理解上面两个概念,就必须搞清楚如下的问题: 参与者都有谁?依赖:谁依赖于谁?为什么 ...

  6. Spring4学习回顾之路02—IOC&DI

    IOC&DI介绍 ●IOC:(Inversion of Control) :控制反转(反向获取资源) 其思想是反转资源获取的方向.传统的资源上查找方式要求组件向容器发起请求查找资源,作为回应, ...

  7. Spring框架——IOC&DI

    Spring Spring 目标 内容 Spring与web整合的原理 Spring 中包含的关键特性 Spring架构图 企业级框架 企业级系统 IOCDI IOC DI IOC和DI 为什么使用依 ...

  8. Spring IOC/DI和AOP原理

    一 IOC/DI 1. 概念机原理 IOC: Inversion of Control(控制反转)是一种设计思想,就是容器控制应用程序所需要外部资源的创建和管理,然后将其反转给应用程序.对象及其依赖对 ...

  9. 深入理解IoC/DI

    ------------------------------------------------------------------------ 理解IoC/DI 1.控制反转 --> 谁控制谁 ...

随机推荐

  1. CACTI命令行添加DEVICE/GRAPH/TREE

    有时要加入大量的机器到 Cacti ,直接修改 Cacti  还是很复杂的.所以最好还是通过他本身提供的工具来实现. Cacti  早就为我们想到过这个问题了.这些工具就在   cacti/cli 目 ...

  2. WPF通过EventTrigger改变其他控件的值

    场景:点击TextBox后弹出Poppup 原理:使用EventTrigger后触发StoryBoard,通过StoryBoard改变其他控件的值. 参考代码: <Grid> <Gr ...

  3. Ext.ux.grid.feature.Searching 解析查询参数,动态产生linq lambda表达式

    上篇文章中http://www.cnblogs.com/qidian10/p/3209439.html我们介绍了如何使用Grid的查询组建,而且将查询的参数传递到了后台. 那么我们后台如何介绍参数,并 ...

  4. Python Garbage Collection 与 Objective-C ARC

    转载请注明出处 http://blog.csdn.net/u014205968/article/details/69389363 Python GC 与 Objective-C ARC 提起GC(Ga ...

  5. UMEditor(Ueditor mini)修改图片上传路径

    UMEditor(Ueditor mini)修改图片上传路径 imageUp.ashx string pathbase = "/UpLoad/images/"; //保存文件夹在网 ...

  6. node学习笔记6——自定义模块

    自定义模块三大关键词: require——引入模块: exports——单个输出: module——批量输出. 从例子下手: 1.创建module.js: exports.a=22; exports. ...

  7. 怎么解决JSP中出现乱码的问题

    首先我们先了解一下问题的原因.一般情况在在每个JSP页的头部都有这样一条语句: 这条语句决定了此页面使用GB2312编码形式,而在数据库中一般用的是iso-8859-1字符集存储数据. 而Java程序 ...

  8. 关于Unity点击New创建新项目没反应的解决方案

    1.登出Unity 2.再登录Unity 3.再次点击New,可以

  9. 关于Unity中Cg的基本语法和使用

    Cg是类似于C语言的发展起来的图形编程语言,Cgraphics,它的很多表达式if...else...和C语言非常相像,也和C#非常相像. 由于Shader是写给显卡执行的,所以没有输出语句来调试,很 ...

  10. linux sh 读取文件内容,if判读语句,变量var打印

    #!/bin/bash #1 读取文件 并显示 cat state.txt | while read line do echo $line done #2 读取文件 并显示 cat state.txt ...