第一章 Spring的核心(3节 上)

 
1.3理解DI
       尽管spring已经做了很多了,但是DI依旧是Spring的核心。听起来DI好像很高深,实际上不是。实际上,在项目中使用DI,你会发现代码会简单很多,容易理解和测试。
       但是,DI的意思是什么?
1.3.1 Injecting dependencies
       起初,DI更多的被人叫做IoC,Inversion of control,但04年的一篇文章,Martin flower的,说控制这个方面的已经改变了。他总结到,现在已经变成了获得依赖。基于这个发现,他引用了短语,Dependency Injection,这个能更好的说明现在的机制。
       一个复杂的程序(比HelloWorld.java复杂的多)由2个以上的类来组合并执行业务逻辑。传统上,每个对象负责得到自己需要获得的那个写作(依赖的)对象的实例。这就产生了高耦合的代码。
       在项目中使用DI,那么初始化时,各个对象间的依赖关系在初始化时就给出了;这是通过在系统中协调每个对象的外部实体完成的。换句话讲,依赖关系注入到对象中。因此,DI的含义是倒置责任,根据一个对象如何得到协作的对象的实例。

DI就是对象通过其他方法得到依赖关系,而不是通过对象本身的方法。

 

DI得到的最大的好处是松耦合。If an object only knows about its dependencies by their interface (not their implementation or how they were instantiated) then the dependency can be swapped out with a different implementation without the depending object knowing the difference.如果一个对象只通过接口们来知道它的依赖关系(而不是实现或者他们如何初始化的),那么依赖关系可以通过不同的实现来得到,而依靠的对象不需要知道不同处。

例如,Foo类(图1.2)只通过Bar的接口来调用Bar,那么实际如何实现Bar对于Foo来说没有什么重要的。Bar可以是一个本地的POJO类,一个远程接口,一个EJB或者一个测试程序-Foo不需要了解。

如果你感兴趣,那么你一定急于知道如何用代码实现。下面就是。。。

 

1.3.2 实战Dependency Injection

假设公司的对市场的分析研究的结果,决定你的客户需要一个骑士-这个意思是:他们需要java类来表示骑士。在了解需求后,你知道了他们需要用类来表示亚瑟王的圆桌骑士,他们上船去寻找圣杯。(老外真能瞎想啊)

这是个奇怪的需求,但你已经习惯了市场小组奇怪的想法了。因此,你打开IDE并写下来下面的代码:

List1.5 Knight bean

package com.springinaction.chapter01.knight;

 

public class KnightOfRoundTable {

    private String name;

    private HolyGrailQuest quest;

    public KnightOfRoundTable(String name) {

       this.name = name;

        quest = new HolyGrailQuest();

    }

   

    public HolyGrail embarkOnQuest() throws GrailNotFoundException{

       return quest.embark();     

    }

      

}

1.5中,Knight的名字由构造器作为一个参数构造。它的构造器通过初始化了一个HolyGrailQuest来构造了一个骑士的quest。实现HolyGrailQuest很简单

List 1.6  

package com.springinaction.chapter01.knight;

 

public class HolyGrailQuest {

    public HolyGrailQuest(){}

   

    public HolyGrail embark() throws GrailNotFoundException{

      

       HolyGrail grail = null;

       //Look for grail

      

       retrun grail;

    }

}

很满意你的代码,自豪的把代码放入版本控制服务器上。你希望让市场小组看到,但总觉得什么做的不对。半天后你才发现,你没写单元测试。

Knight的单元测试

单元测试总是很有用的….

1.7 code of test

package com.springinaction.chapter01.knight;

 

import junit.framework.TestCase;

 

public class KnightOfRoundTableTest extends TestCase {

    public void testEmbarkOnQuest() throws GrailNotFoundException {

       KnightOfRoundTable knight  = new KnightOfRoundTable("Bedivere");

       HolyGrail grail = knight.embarkOnQuest();

      

       assertNotNull(grail);

       assertTrue(grail.isHoly());

    }

}

写完这个test后,你开始写HolyGrailQuest的测试。但在你开始前,你意识到KnightOfRoundTableTest间接的测试了HolyGrailQuest。你还想测试一下偶然情况,如果embark()返回null?如果抛出了异常呢?

 

       谁调用谁?

       现在主要原因是KnightOfRoundTable如何得到一个HolyGrailQuest。不论是初始化一个HolyGrailQuest对象还是通过JNDI调用得到的,每一个knight负责得到自己的quest(图1.3所示)。基于这些,每次你测试KnightOfRoundTable,就是间接的测试了HolyGrailQuest

还有,没法用不同的方法测试HolyGrailQuest不同的行为(例如,返回null或者抛出异常)。要测试的话,只能写一些虚假的代码。但这样就要修改KnightOfRoundTable的代码,然后再改回来。麻烦不?

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值