介绍 IOC

作者:冰云 icecloud(AT)sina.com
BLOG: http://icecloud.51.net

时间: 2004.02.15

 

一、什么是 IOC

IoC 就是 Inversion of Control ,控制反转。在 Java 开发中, IoC 意味着将你设计好的类交给系统去控制,而不是在你的类内部控制。这称为控制反转。

 

下面我们以几个例子来说明什么是 IoC

 

假设我们要设计一个 Girl 和一个 Boy 类,其中 Girl kiss 方法,即 Girl 想要 Kiss 一个 Boy 。那么,我们的问题是, Girl 如何能够认识这个 Boy

 

    在我们中国,常见的MM与 GG 的认识方式有以下几种

    1 青梅竹马;   2 亲友介绍;   3 父母包办

 

    那么哪一种才是最好呢?

    青梅竹马 Girl 从小就知道自己的 Boy

   

 

 

 

public class Girl {  
    void kiss(){
       Boy boy = new Boy();
    }
}

 

 

    然而从开始就创建的 Boy 缺点就是无法在更换。并且要负责 Boy 的整个生命周期。如果我们的 Girl 想要换一个怎么办?(笔者严重不支持 Girl 经常更换 Boy

 

    亲友介绍 :由中间人负责提供 Boy 来见面

 

       


public
class Girl {
    void kiss(){
       Boy boy = BoyFactory.createBoy();      
    }
}

 

    亲友介绍,固然是好。如果不满意,尽管另外换一个好了。但是,亲友 BoyFactory 经常是以 Singleton 的形式出现,不然就是,存在于 Globals ,无处不在,无处不能。实在是太繁琐了一点,不够灵活。我为什么一定要这个亲友掺和进来呢?为什么一定要付给她介绍费呢?万一最好的朋友爱上了我的男朋友呢?

 

    父母包办 :一切交给父母,自己不用费吹灰之力,只需要等着 Kiss 就好了。

 

 

      


public

class Girl {
    void kiss(Boy boy){
       // kiss boy  
      boy.kiss();
    }
}

    Well ,这是对 Girl 最好的方法,只要想办法贿赂了 Girl 的父母,并把 Boy 交给他。那么我们就可以轻松的和 Girl Kiss 了。看来几千年传统的父母之命还真是有用哦。至少 Boy Girl 不用自己瞎忙乎了。

    这就是 IOC ,将对象的创建和获取提取到外部。由外部容器提供需要的组件。

 

    我们知道好莱坞原则 “Do not call us, we will call you.” 意思就是, You, girlie, do not call the boy. We will feed you a boy

 

    我们还应该知道依赖倒转原则 Dependence Inversion Princinple DIP

 

 

Eric Gamma 说,要面向抽象编程。面向接口编程是面向对象的核心。

组件应该分为两部分,即

Service , 所提供功能的声明

Implementation , Service 的实现

好处是:多实现可以任意切换,防止 everything depends on everything 问题.即具体依赖于具体。

所以,我们的 Boy 应该是实现 Kissable 接口。这样一旦 Girl 不想 kiss 可恶的 Boy 的话,还可以 kiss 可爱的 kitten 和慈祥的 grandmother

 

 

二、 IOC type

    IoC Type 指的是 Girl 得到 Boy 的几种不同方式。我们逐一来说明。

 

    IOC type 0 不用 IOC

 

 

public class Girl implements Servicable {

    private Kissable kissable;

    public Girl() {
        kissable = new Boy();
    }

    public void kissYourKissable() {
        kissable.kiss();
    }

}

 

 

    Girl 自己建立自己的 Boy ,很难更换,很难共享给别人,只能单独使用,并负责完全的生命周期。

 

    IOC type 1 先看代码:

 

 

public class Girl implements Servicable {

    Kissable kissable;

    public void service(ServiceManager mgr) {
        kissable = (Kissable) mgr.lookup( kissable);
    }

    public void kissYourKissable() {
        kissable.kiss();
    }

}

 

 

    这种情况出现于 Avalon Framework 。一个组件实现了 Servicable 接口,就必须实现 service 方法,并传入一个 ServiceManager 。其中会含有需要的其它组件。只需要在 service 方法中初始化需要的 Boy

    另外, J2EE 中从 Context 取得对象也属于 type 1

 

    它依赖于配置文件

 

<container>
    <component name= kissable class= Boy">              
       <configuration>
</configuration>
    </component>

    <component name= girl" class= Girl" />
</container>

 

 

    IOC type 2

   

 

public class Girl {

    private Kissable kissable;

    public void setKissable(Kissable kissable) {
        this .kissable = kissable;
    }

    public void kissYourKissable() {
        kissable.kiss();
    }

}

 

 

    Type 2 出现于 Spring Framework ,是通过 JavaBean set 方法来将需要的 Boy 传递给 Girl 。它必须依赖于配置文件。

       

 

<beans>
    <bean id= boy" class= Boy"/>
    <bean id= girl class= Girl">
        <property name= kissable">
           <ref bean= boy"/>
        </property>
    </bean>
</beans>

 

 

IOC type 3

 

 

public class Girl {

    private Kissable kissable;

    public Girl(Kissable kissable) {
        this .kissable = kissable;
    }

    public void kissYourKissable() {
        kissable.kiss();
    }

}

 

 

    这就是 PicoContainer 的组件 。通过构造函数传递 Boy Girl

 

 

 

PicoContainer container = new DefaultPicoContainer();
container.registerComponentImplementation(Boy. class );
container.registerComponentImplementation(Girl. class );
Girl girl = (Girl) container.getComponentInstance(Girl. class );
girl.kissYourKissable();

 

 

    关于 PicoContainer ,作者后续文章会详细介绍。

 

作者语:   

    Well ,以上的这些理论部分有些已经有了新的定义了。过些天我会再写一些文章具体说明。比如,原来的三种 type 结构现在已经重新定义为依赖注射的许多层次。

IoC 很年轻,还在发展。伴随着 IOC 的发展, AOP COP SOP 等等都在不断的发展。作为程序员,随时关注着新的思想的发展是一件很轻松愉快的事情。有没有人愿意和我一起探讨学习共同进步呀!

   

 

参考资料

 

    1 本文主要插图及文字来源于 ThoughtWorks 公司的 Jon Tirsén Aslak Hellesøy PicoContainer 的两位开发者), 2003 年在 Java Polis 的演讲 PPT 。有删改。

http://www.picocontainer.org/presentations/JavaPolis2003.ppt

http://www.picocontainer.org/presentations/JavaPolis2003.pdf

 

    2 DIP Robert C Martin, Bob 大叔的优秀论文

http://www.objectmentor.com/resources/articles/dip.pdf

 

3 Dependency Injection  依赖注射, Matrin Fowler DIP 的扩展

http://www.martinfowler.com/articles/injection.html

 

4 IOC 框架

PicoContainer 优秀的 IOC 框架

http://picocontainer.org/

Avalon

http://avalon.apache.org/

Spring Framework

http://www.springframework.org/

HiveMind

http://jakarta.apache.org/commons/hivemind

 

5 中文资料

程序匠:国内研究 Pico 的先驱

http://douleimi.vicp.net/space/start

Jdon :板桥也在研究

http://www.jdon.com/design.htm

Spring   Framework 中文论坛

http://xglw.51.net/5team/springframework/index.php

Avalon 中文资料

http://www.huihoo.org/apache/avalon/introduction.html

ERPROAD

http://www.erproad.org/index.asp?vt=bycat&cat_id=37

Open Heart

http://blogbus.com/blogbus/blog/index.php?blogid=2529&cat=5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值