/**
作者:Willpower
来源:Rifoo Technology(http://www.rifoo.com)
时间:2005-12-26
备注:转载请保留以上声明
**/
这一节主要简单介绍了依赖注入的思想。强调了依赖注入是Spring框架的一种核心模式。
下图简单的说明了这种依赖注入的情况。客户端使用到了另一个我们称为service的类。客户端有自己的属性用来接受这个service。这个service被包装成一个接口,因此客户端是看不到service的具体实现的。但是这个并不完全是松耦合的,我们仍然要自己创建service。在依赖注入的思想里,一种第三方的控制器或装配器用来创建一个客户端和一个service,然后set一个service的引用来满足依赖注入的要求。

其实我们并不一定需要一个轻量级容器来使用依赖注入的模式。我们只需要三步就可以使用依赖注入模式来完成模块的解耦:
1 将这个service类包装成一个接口
2 给客户端添加一个属性,做为这个service接口的引用
3 使用一个第三方框架或自己编写的代码来开发这个service并设置该属性。
下面我们来看如何改写第一节里的范例代码:
Example 1-4. ArrayListRentABike.java (renamed from RentABike.java)
import java.util.*;
public class ArrayListRentABike implements RentABike {
private String storeName;
final List bikes = new ArrayList( );
public ArrayListRentABike( ) { initBikes( ); }
public ArrayListRentABike(String storeName) {
this.storeName = storeName;
initBikes( );
}
public void initBikes( ) {
bikes.add(new Bike("Shimano", "Roadmaster", 20, "11111", 15, "Fair"));
bikes.add(new Bike("Cannondale", "F2000 XTR", 18, "22222", 12, "Excellent"));
bikes.add(new Bike("Trek", "6000", 19, "33333", 12.4, "Fair"));
}
public String toString( ) { return "RentABike: " + storeName; }
public List getBikes( ) { return bikes; }
public Bike getBike(String serialNo) {
Iterator iter = bikes.iterator( );
while(iter.hasNext( )) {
Bike bike = (Bike)iter.next( );
if(serialNo.equals(bike.getSerialNo( ))) return bike;
}
return null;
}
}
Example 1-5. RentABike.java
import java.util.*;
interface RentABike {
List getBikes( );
Bike getBike(String serialNo);
}
大家看到了,RentABike由原来的具体类改成了一个接口,而具体实现类是由ArrayListRentABike来完成的。实现类里的操作和方法和第一节里的原RentABike是一模一样的。
再来看看客户端的代码:
Example 1-6. CommandLineView.java
import java.util.*;
public class CommandLineView {
private RentABike rentaBike;//接口的引用
public CommandLineView( ) { }
//set接口
public void setRentaBike(RentABike rentaBike) {
this.rentaBike = rentaBike;
}
public RentABike getRentaBike( ) { return this.rentaBike;}
public void printAllBikes( ) {
System.out.println(rentaBike.toString( ));
Iterator iter = rentaBike.getBikes( ).iterator( );
while(iter.hasNext( )) {
Bike bike = (Bike)iter.next( );
System.out.println(bike.toString( ));
}
}
}
大家应该注意到了吧,这里客户端有一个属性放置RentABike接口的引用。
最后,我们有一个控制器或装配器来创建所有的对象,并设置它们的属性。
Example 1-7. RentABikeAssembler.java
public class RentABikeAssembler {
public static final void main(String[] args) {
//创建一个客户端对象
CommandLineView clv = new CommandLineView( );
//装配器给出了接口的具体实现,所谓面向接口的编程
RentABike rentaBike = new ArrayListRentABike("Bruce's Bikes");
//设置客户端对象的属性,将接口通过构造方法的模式“注入”
clv.setRentaBike(rentaBike);
//调用客户端对象的内部方法
clv.printAllBikes( );
}
}
实际上,以上操作就完成了三个步骤的依赖注入模式。
我们运行程序,可以得到和第一节同样的结果:
C:/RentABikeApp/out>java RentABikeAssembler
RentABike: Bruce's Bikes
Bike : manufacturer -- Shimano
: model -- Roadmaster
: frame -- 20
: serialNo -- 11111
: weight -- 15.0
: status -- Fair.
Bike : manufacturer -- Cannondale
: model -- F2000 XTR
: frame -- 18
: serialNo -- 22222
: weight -- 12.0
: status -- Excellent.
Bike : manufacturer -- Trek
: model -- 6000
: frame -- 19
: serialNo -- 33333
: weight -- 12.4
: status -- Fair.
大家现在看到了一个不用特定容器而实现的简单的依赖注入。通过一个装配器来完成注入操作。其实最终这个装配器会用Spring框架来取代。Spring会为我们创建对象和设置属性。
下图是一个J2EE应用程序使用service locator来管理其依赖的简图,service locator是J2EE核心设计模式之一,它经常被用在命名和服务定位上。具体请参考相关文章,我就不多解释了。

service location这种设计模式把依赖从应用程序中完全脱离了出来。我们后面会陆续讲到。
作者:Willpower
来源:Rifoo Technology(http://www.rifoo.com)
时间:2005-12-26
备注:转载请保留以上声明
**/
这一节主要简单介绍了依赖注入的思想。强调了依赖注入是Spring框架的一种核心模式。
下图简单的说明了这种依赖注入的情况。客户端使用到了另一个我们称为service的类。客户端有自己的属性用来接受这个service。这个service被包装成一个接口,因此客户端是看不到service的具体实现的。但是这个并不完全是松耦合的,我们仍然要自己创建service。在依赖注入的思想里,一种第三方的控制器或装配器用来创建一个客户端和一个service,然后set一个service的引用来满足依赖注入的要求。

其实我们并不一定需要一个轻量级容器来使用依赖注入的模式。我们只需要三步就可以使用依赖注入模式来完成模块的解耦:
1 将这个service类包装成一个接口
2 给客户端添加一个属性,做为这个service接口的引用
3 使用一个第三方框架或自己编写的代码来开发这个service并设置该属性。
下面我们来看如何改写第一节里的范例代码:
Example 1-4. ArrayListRentABike.java (renamed from RentABike.java)
import java.util.*;
public class ArrayListRentABike implements RentABike {
private String storeName;
final List bikes = new ArrayList( );
public ArrayListRentABike( ) { initBikes( ); }
public ArrayListRentABike(String storeName) {
this.storeName = storeName;
initBikes( );
}
public void initBikes( ) {
bikes.add(new Bike("Shimano", "Roadmaster", 20, "11111", 15, "Fair"));
bikes.add(new Bike("Cannondale", "F2000 XTR", 18, "22222", 12, "Excellent"));
bikes.add(new Bike("Trek", "6000", 19, "33333", 12.4, "Fair"));
}
public String toString( ) { return "RentABike: " + storeName; }
public List getBikes( ) { return bikes; }
public Bike getBike(String serialNo) {
Iterator iter = bikes.iterator( );
while(iter.hasNext( )) {
Bike bike = (Bike)iter.next( );
if(serialNo.equals(bike.getSerialNo( ))) return bike;
}
return null;
}
}
Example 1-5. RentABike.java
import java.util.*;
interface RentABike {
List getBikes( );
Bike getBike(String serialNo);
}
大家看到了,RentABike由原来的具体类改成了一个接口,而具体实现类是由ArrayListRentABike来完成的。实现类里的操作和方法和第一节里的原RentABike是一模一样的。
再来看看客户端的代码:
Example 1-6. CommandLineView.java
import java.util.*;
public class CommandLineView {
private RentABike rentaBike;//接口的引用
public CommandLineView( ) { }
//set接口
public void setRentaBike(RentABike rentaBike) {
this.rentaBike = rentaBike;
}
public RentABike getRentaBike( ) { return this.rentaBike;}
public void printAllBikes( ) {
System.out.println(rentaBike.toString( ));
Iterator iter = rentaBike.getBikes( ).iterator( );
while(iter.hasNext( )) {
Bike bike = (Bike)iter.next( );
System.out.println(bike.toString( ));
}
}
}
大家应该注意到了吧,这里客户端有一个属性放置RentABike接口的引用。
最后,我们有一个控制器或装配器来创建所有的对象,并设置它们的属性。
Example 1-7. RentABikeAssembler.java
public class RentABikeAssembler {
public static final void main(String[] args) {
//创建一个客户端对象
CommandLineView clv = new CommandLineView( );
//装配器给出了接口的具体实现,所谓面向接口的编程
RentABike rentaBike = new ArrayListRentABike("Bruce's Bikes");
//设置客户端对象的属性,将接口通过构造方法的模式“注入”
clv.setRentaBike(rentaBike);
//调用客户端对象的内部方法
clv.printAllBikes( );
}
}
实际上,以上操作就完成了三个步骤的依赖注入模式。
我们运行程序,可以得到和第一节同样的结果:
C:/RentABikeApp/out>java RentABikeAssembler
RentABike: Bruce's Bikes
Bike : manufacturer -- Shimano
: model -- Roadmaster
: frame -- 20
: serialNo -- 11111
: weight -- 15.0
: status -- Fair.
Bike : manufacturer -- Cannondale
: model -- F2000 XTR
: frame -- 18
: serialNo -- 22222
: weight -- 12.0
: status -- Excellent.
Bike : manufacturer -- Trek
: model -- 6000
: frame -- 19
: serialNo -- 33333
: weight -- 12.4
: status -- Fair.
大家现在看到了一个不用特定容器而实现的简单的依赖注入。通过一个装配器来完成注入操作。其实最终这个装配器会用Spring框架来取代。Spring会为我们创建对象和设置属性。
下图是一个J2EE应用程序使用service locator来管理其依赖的简图,service locator是J2EE核心设计模式之一,它经常被用在命名和服务定位上。具体请参考相关文章,我就不多解释了。

service location这种设计模式把依赖从应用程序中完全脱离了出来。我们后面会陆续讲到。