也谈谈我对IoC的理解

标签: ioc 理解 | 发表时间:2013-06-07 00:35 | 作者:以利亚
出处:http://www.cnblogs.com/

  今天看到一篇 帖子谈到了对IoC的理解,于是我自己也忍不住跳出来“理解”一番,其实我当年也被“依赖注入、控制反转”这八个字折腾的够呛,但是搞明白之后就会发现这几个字、包括IoC这个名字都纯粹是唬人的,于是今天准备用三张图来说明白这件事。

  首先,IoC和DI说的是一件事,它们的中文名分别是IoC(控制反转)和DI(依赖注入),要说依赖注入,就要先说说依赖倒置原则。

  以下是直接贴自百度知道的概念:所谓依赖倒置原则就是要依赖于抽象,不要依赖于具体。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。面向过程的开发,上层调用下层,上层依赖于下层,当下层剧烈变动时上层也要跟着变动,这就会导致模块的复用性降低而且大大提高了开发的成本。面向对象的开发很好的解决了这个问题,一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。

  这当中提到了分层的概念,在“害死人”的三层架构当中,我们让UI引用BLL,让BLL引用DAL,也就是如下图所示,领域层里new了一个数据层的对象。

  我图画的不好,领域层既然要new一个数据层对象,那么它就需要了解数据层对象的public成员,这样上层就依赖了下层,相当于把下层“拉”进了上层当中,形成了一种强依赖,在此当中数据层对象的生命周期是由领域层控制的(可能写在一个using块当中)。

  为了松散耦合,改为如下方式:

  在领域层当中提供一个接口(IRepository),让数据层来实现这个接口中的方法,这样一来领域层就无需引用数据层的dll了,数据层只需要知道领域层的接口即可,如此这个依赖关系就倒了个个,之后领域层要持有一个接口成员,这个成员是由领域层的构造函数赋值的(这个过程称为“构造注入”,是依赖注入的一种形式,GoF设计模式当中大量运用了这种手段)。

  如此一来我们就完成了一个依赖倒置的示例,那么这个数据层的接口对象总要有一个地方来new它,而且显然是在代码的“高层”new出来的,那么我们放在什么地方来new它呢?如下图:

  首先撇开图中的IoC部分不谈,我们大可以在展现层new一个数据层对象,然后沿着每一层的构造函数传递下去,这称为“穷人的依赖注入”,而这显然要求展现层引用底层的dll,是不合理的。

  这样一来,就需要展现层去请求一个工厂类,让这个工厂类来负责创建数据层对象,然后把这个对象交给展现层,再传递下去。这个工厂类就是我们所谓的IoC容器。

  这个工厂类内部通常包含一个私有的Dictionary<name,object>,可以根据名字来获取对象,对象具体的创建过程可以是反射一个配置好的XML,也可以是通过其他手段获取类名来反射创建,同时这个工厂也可以负责对象是否单例以及是否延迟加载等细节,另外对象的生命周期也是由这个工厂负责的。不过这个工厂有一个弊端,就是需要在站点启动的时候把它启动起来。

  事实上,不光是数据层,连同领域层和服务层的对象,也可以从展现层通过IoC容器“推”到下层,这就是一套松散耦合的系统。

  这样的系统方便单元测试,由于耦合度低方便零件的插拔,麻烦在于单步调试,而且对开发人员的OO能力有要求。

  在实际应用当中我们大可以写一个自己的容器,如果你是做平台的,就可以写一些配置界面,让用户配置你功能的二次开发类,可以把这些二次开发接口的对象反射进容器里进行保存,这样一来我们的平台根本无需知道二次开发人员的子类是怎么实现,只需要知道这个类的位置即可。

  最后,对于“依赖注入、控制反转”的理解,说白了,依赖注入就是我不去找你了,有人告诉我你在哪。控制反转就是控制权给你了,我不new了你来new。

本文链接

相关 [ioc 理解] 推荐:

【连载 Spring IoC】IoC的理解与Spring IoC的架构介绍

- - 码农博客
研究Spring的人太多了,网上的资料也数不胜数,今天开始笔者也将开始分析Spring以及Spring的源码,主要为自己更好地学习和掌握Spring的原理,其次分享到网上也是供大家学习和拍砖. 第一篇,没有写Spring的整体架构,原因是笔者对Spring的整体架构也不是非常熟悉,虽然网上有很多资料查询参考,但是笔者想不是自己研究的,就没必要搬过来,笔者写下的内容都是笔者亲自学习和研究的,并且可能写下来也会根据笔者的理解深度和广度不断更新.

也谈谈我对IoC的理解

- - 博客园_首页
  今天看到一篇 帖子谈到了对IoC的理解,于是我自己也忍不住跳出来“理解”一番,其实我当年也被“依赖注入、控制反转”这八个字折腾的够呛,但是搞明白之后就会发现这几个字、包括IoC这个名字都纯粹是唬人的,于是今天准备用三张图来说明白这件事.   首先,IoC和DI说的是一件事,它们的中文名分别是IoC(控制反转)和DI(依赖注入),要说依赖注入,就要先说说依赖倒置原则.

需求变化与IoC

- - 酷壳 - CoolShell.cn
【感谢 Todd投递本文 – 微博帐号:@ weidagang 】. 程序员XX遭遇车祸成植物人,医生说活下来的希望只有万分之一,唤醒更为渺茫. 可他的Lead和亲人没有放弃,他们根据XX工作如命的作风,每天都在他身边念:“XX,需求又改了,该干活了,你快来呀. ”,奇迹终于发生了,XX醒来了,第一句话:“需求又改了.

泛型理解

- - ITeye博客
泛型不是协变的,例如下面的代码不是正确的. 之所以声明泛型方法,一般是因为您想要在该方法的多个参数之间宣称一个类型约束. 例如,下面代码中的ifThenElse()方法,根据它的第一个参数的布尔值,它将返回第二个或第三个参数:. 注意,您可以调用ifThenElse(),而不用显式地告诉编译器,您想要T的什么值.

理解inode

- - haohtml's blog
inode是一个重要概念,是理解Unix/Linux文件系统和硬盘储存的基础. 我觉得,理解inode,不仅有助于提高系统操作水平,还有助于体会Unix设计哲学,即如何把底层的复杂性抽象成一个简单概念,从而大大简化用户接口. 下面就是我的inode学习笔记,尽量保持简单. 理解inode,要从文件储存说起.

理解OAuth 2.0

- - 阮一峰的网络日志
OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版. 本文对OAuth 2.0的设计思路和运行流程,做一个简明通俗的解释,主要参考材料为 RFC 6749. 为了理解OAuth的适用场合,让我举一个假设的例子. 有一个"云冲印"的网站,可以将用户储存在Google的照片,冲印出来.

理解云计算

- 车东 - oneoo&#39;s 私家花园
  现在互联网最热门的关键字“云计算”,大大小小的公司纷纷加入到这块领域. 简单来说,目前的“云计算”主要分为:SaaS、PaaS和IaaS三大类.   其中SaaS云计算,为软件即服务的概念. 把传统客户端软件部署在互联网上,用户只需要一个浏览器就可以使用到软件的模式. 其实早在2000年就已经有B/S结构的软件服务,与现在所说的SaaS云计算相近,但此前的B/S结构软件服务,数据库等服务端是需要用户自行部署的,而非由软件提供商进行统一部署.

深入理解JVM

- 小伟 - ITeye论坛最新讨论
1   Java技术与Java虚拟机. 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API). 图1   Java四个方面的关系. 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件).

理解RESTful架构

- InterMa - 阮一峰的网络日志
越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency)、高并发等特点. 网站开发,完全可以采用软件开发的模式. 但是传统上,软件和网络是两个不同的领域,很少有交集;软件开发主要针对单机环境,网络则主要研究系统之间的通信.