什么是Ioc(Inversion of Control) :: 技术点滴

来源: BlogBus 原始链接: http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=129472 存档链接: https://web.archive.org/web/20041027221159id_/http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=129472


技术点滴 几年的软件研发做下来,接触的技术,零零碎碎加起来,居然手指不够数了。不少东西,是帮工程部门解决完就扔一旁。弃之可惜,何不借这网络一角,留下一点记忆?遂有此Blog。 <<<Spring Framework文档资源 | 主页 | GMail里的邮件能否永久删除>>> 什么是Ioc(Inversion of Control) 2004-04-06 这篇短文基本上是改编自Martin Fowler的Inversion of Control Containers and the Dependency Injection pattern,目的呢,是让读者能够在最短时间内了解IoC的概念。这也是我一贯的“风格”:最短的文字、最精要的内容、最清晰的说明。希望我能做到,自勉^_^ 在 J2EE 应用开发中,经常遇到的问题就是:如何将不同的组件组装成为一个内聚的应用程序? IoC 模式可以解决这个问题,其目标是将组件的配置与使用分离开。 IoC , Inversion of Control ,控制反转 [1] ,其原理是基于 OO 设计原则的 The Hollywood Principle : Don't call us, we'll call you 。也就是说,所有的组件 [2] 都是被动的( Passive ),所有的组件初始化和调用都由容器负责。组件处在一个容器当中,由容器负责管理。 要说明 IoC 模式最好的方法是使用代码。下边是一段正常的代码。 class ClassA ... public String aMethod (String arg){ String result = instanceOfClassB. bMethod (); do something; return result; } 在上边的代码里,我们要解决的问题是: ClassA 如何获得 ClassB 的实例?一个最直接的方法是在 aMethod 里声明: IClassB instanceOfClassB = new ClassB(); 这里使用了一个接口 IClassB 。 问题是,如果出现这样的情况:继续使用 ClassA ,但要求用 IClassB 的另一个实现 ClassB2 代替 ClassB 呢?更概括一点说: ClassA 怎样才能找到 IClassB 的具体实现?很明显,上述代码增加 ClassA 和 ClassB 的耦合度,以致于无法在不修改 ClassA 的情况下变更 IClassB 的具体实现。 IoC 模式就是用于解决这样的问题。当然,还有其他的方法,比如 Service Locator 模式,但现在我们只关注 IoC 。如前所述, IoC 容器负责初始化组件(如 IClassB ),并将实例交给使用者。使用代码或配置文件以声明的方式将接口与实例关联起来, IoC 容器负责进行实际的调用处理。对于调用者,只需要关注接口就行了。 根据实例传入方式的不同, IoC 分为 type 1 IoC (接口注入 [3] )、 type 2 IoC (设值方法注入)和 type 3 IoC (构造子注入)。分别用代码说明如下: type 1 IoC (接口注入) public interface GetClassB { void getClassB(IClassB instanceOfClassB); } class ClassA implements GetClassB… IClassB instanceOfClassB; void getClassB(IClassB instanceOfClassB) { this.instanceOfClassB = instanceOfClassB; } type 2 IoC (设值方法注入) class ClassA... IClassB instanceOfClassB; public void setFinder(IClassB instanceOfClassB) { this.instanceOfClassB = instanceOfClassB; } type 3 IoC (构造子注入) class ClassA… ClassB instanceOfClassB; public classA(IClassB instanceOfClassB) { this. instanceOfClassB = instanceOfClassB; } Spring 使用的是 type 2 IoC 。 [1] 在 Martin Fowler 的 Inversion of Control Containers and the Dependency Injection pattern 一文中,作者提出本模式更准确的名称应该是 Dependency Injection 。考虑到使用上的习惯,在本文档中我们将继续使用 IoC 的概念。 [2] 同一篇文章中, Martin Fowler 还提出了 Componet (组件)与 Service (服务)的区别问题。我个人认为“组件”更有助于帮助我们理解 IoC 的概念,所以在本文档中使用“组件”来代表“组件或服务” [3] 如上所述,注入是另一种说法,此处只用于辅助说明。 linrun 发表于 2004-04-06 00:50 引用Trackback(0) | 编辑 Comments 发表评论 最近更新 我还活着 tomcat mysql 连接池 配置 中文 Commons Logging + Log4j快速入门 最近Blogbus很不稳定 London Bloggers 新分类Java basic 换模板了 fy GMail tips Google Logo For The Athens 2004 Olympic Games 淘到一个“拼接式自我资产分析图” 逝者如斯 反向链接 访问统计 DVD Movies