依赖注入(DI)和控制反转(IOC)

0X1 什么是依赖注入

  依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点。在程序运行过程中,客户类不直接实例化具体服务类实例,而是客户类的运行上下文环境或专门组件负责实例化服务类,然后将其注入到客户类中,保证客户类的正常运行。详细的介绍可以阅读上一篇博文:http://www.cnblogs.com/dazhuangtage/p/5672190.html

0X2 什么是控制反转

  在解释什么是控制反转的之前我们先引入上一篇博文一个博友在评论中提的问题:依赖注入和控制反转不是一回事吗?

  在我看来,控制反转这种思想最终的实现要依赖与依赖注入这种实现方式。控制反转只是把高低层的关系发生变化,以前底层模块在实现功能的时候可能会依赖于高层模块,通过控制反转可以让底层模块依赖于一个接口,如果这个时候高层模块要使用底层模块的话就必须

实现这个接口,然后通过依赖注入的方式把高层模块的实现类注册到底层模块中使用。

  有可能上面的解释大家比较懵,下面我会通过举例来进一步介绍控制反转这种设计模式。

0X3 一个例子理解控制反转

  

  从上图可以看出驾驶者依赖“汽车“和“火车”这两个类,如果驾驶员需要开汽车话的就需要实例化一个汽车类,需要开火车的话则需要实例化一个火车类

  

1
2
3
4
//开汽车
汽车 cat=new 汽车();
cat.Stop();
//开火车省略。。

  这个时候如果说我们需要开飞机怎么办?传统做法则是新建一个飞机类,然后在驾驶者直接实例化飞机类即可。

我们暂把上图的框架成为“自动驾驶系统”,现在"自动驾驶系统"已经拥有了自动开汽车、开飞机、开火车的功能了,你觉得已经很强大了,于是把这套系统卖给了某个公司,但是这家公司的业务不仅限于前三种交通工具,现在这家公司要实现驾驶者可以驾驶飞船,如下图所示

  大家可以看到如果我们的“自动驾驶系统”要实现可以驾驶飞船的话,就需要驾驶者创建“飞船”的对象,这个时候我们的框架还是依赖于外部(因为飞船类在客户那边)。这个就是我们常说的底层模块依赖于高级模块。这种依赖肯定是不行的,随着客户的变化就要改动我们的框架,这种做法肯定不行,我们继续演变。

  现在我们的驾驶者并不直接依赖于某个具体实现类,而且依赖于接口,但是这个时候上图就暴露了一个问题,希望大家先不要看下面的文字,大家可以先思考下上图有什么问题。(上图三个交通工具和接口的关系标识错了,应该是实现)

  上图的设计虽然解决了不用New具体那个对象的问题,但是新的问题也随之而来:驾驶者到底使用哪个实现类?大家都知道接口是不能直接实例化的,能够实例化的只有接口的具体的实现类。OK,为了解决这个问题我们继续演变

  上图我们使用工厂模式,这时候的关系是驾驶者依赖与工厂类,由工厂类具体去创建具体的实现类。根据上图我们再看如果我们实现开飞船,那么它们之间的关系会发生什么样的变化(上图三个交通工具和接口的关系标识错了,应该是实现)

  通过一系列演化,现在两者之间的关系已经彻底发生了改变,以前是底层模块(框架)依赖于高层模块,现在变成了高层模块依赖于底层模块,从上图可以看出,无论你是要开飞船还是开火箭,只要你实现了“交通工具”接口,那么我就可以在工厂类里面给创建出来。这样一来不仅增加了我们系统的可扩展性,也提高了我们系统的整体稳健型。

   最后来总结一下到底什么是控制反转,我的答案已经在文章开头给出了,下面给出维基百科的答案:

    

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

依赖注入(DI)和控制反转(IOC)的更多相关文章

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

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

  2. 依赖注入(DI)和控制反转(IOC)的理解,写的太好了。

    学习过spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  3. 【串线篇】依赖注入DI与控制反转IOC

    DI&IOC 在spring框架中DI与IOC说的其实是一回事 一句话:本来我接受各种参数来构造一个对象,现在只接受一个参数——已经实例化的对象. 也就是说我对对象的『依赖』是注入进来的,而和 ...

  4. 轻松理解 Java开发中的依赖注入(DI)和控制反转(IOC)

    前言 关于这个话题, 网上有很多文章,这里, 我希望通过最简单的话语与大家分享. 依赖注入和控制反转两个概念让很多初学这迷惑, 觉得玄之又玄,高深莫测. 这里想先说明两点: 依赖注入和控制反转不是高级 ...

  5. 话说 依赖注入(DI) or 控制反转(IoC)

    科普:首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程序间的耦合,鄙人学习了一下,看TP官网还没有相关的文章,就写下这篇拙作介绍一下这种设计模式,希望能为TP社区贡献一些 ...

  6. ASP.NET MVC进阶之路:深入理解依赖注入(DI)和控制反转(IOC)

    0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点.在程序运行过程中,客户 ...

  7. PHP 依赖注入(DI) 和 控制反转(IoC)

    要想理解 PHP 依赖注入 和 控制反转 两个概念,就必须搞清楚如下的两个问题: DI —— Dependency Injection 依赖注入 IoC —— Inversion of Control ...

  8. 聊一聊PHP的依赖注入(DI) 和 控制反转(IoC)

    简介 IoC Inversion of Control 控制反转DI Dependency Injection 依赖注入 依赖注入和控制反转说的实际上是同一种东西,它们是一种设计模式,这种设计模式用来 ...

  9. 依赖注入(DI)与控制反转(IOC)

    DI(依赖注入,Dependency Injection),和所谓的IoC(控制反转,Inversion of Control )是一个意思. DI是一种通过接口实现松耦合的设计模式.初学者可能会好奇 ...

随机推荐

  1. iOS根据2个经纬度计算距离

    #pragma mark - calculate distance 根据2个经纬度计算距离 #define PI 3.14159265358979323 +(double) CalculationDi ...

  2. C# 懒人常用异步方法

    Winform this.Invoke(new Action(() => { })); Wpf this.Dispatcher.Invoke(DispatcherPriority.Normal, ...

  3. JAVA 堆设置

    JAVA 堆设置 第四节 堆已经讲得差不多啦,这章我们以一个例子来说说如何设置以及当发生堆溢出的时候怎么排查问题.先看一小段代码:         代码中使用了一个无限循环来为list添加对象,如果采 ...

  4. spring与hibernate整合事务管理的理解

    在谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...

  5. leetcode Sudoku Solver python

    #the define of Sudoku is on this link : http://sudoku.com.au/TheRules.aspx Write a program to solve ...

  6. QF——iOS中的数据库操作:SQLite数据库,第三方封装库FMDB,CoreData

    SQLite数据库: SQLite是轻量级的数据库,适合应用在移动设备和小型设备上,它的优点是轻量,可移植性强.但它的缺点是它的API是用C写的,不是面向对象的.整体来说,操作起来比较麻烦.所以,一般 ...

  7. css background-position (图片裁取)

    语法:background-position : length || length background-position : position || position 取值:length  : 百分 ...

  8. js、css、html判断浏览器的各种版本

    利用正则表达式来判断ie浏览器版本 判断是否IE浏览器 if (document.all) { alert("这个是ie浏览器");} 判断是否IE6浏览器 方法一:if ( /M ...

  9. 如何实现select组件的选择输入过滤作用

    实现select组件的选择输入过滤作用的js代码如下: /** *其中//******之间的部分显示的是在没有选择输入过滤功能的代码上加入的功能代码 ** / (function ( $ ) { $. ...

  10. Bower —— 一个Web的包管理工具

    作者:江剑锋   github地址:https://github.com/bower/bower Bower为何物 Bower是一个Web开发的包管理软件.前端开发中,或多或少,都会以来于现成的fra ...