2009年10月29日星期四

IOC 的手工实现与Guice 实现

IOC 的手工实现与Guice 实现

1. 服务类与实现类
public interface Service {
void go();
}

public class ServiceImpl implements Service {
public void go() {
logger.info("ServiceImpl.class");
}
}

public class MockService implements Service {
public void go() {
logger.info("MockService.class");
}
}

2. 客户类,调用服务类,最原始的实现
public class Client {
public void test(boolean args){
Service service = null;
if(args){
service = new ServiceImpl();
service.go();
}else{
service = new MockService();
service.go();
}
}
}

3. 测试类,但使用了工厂模式
public class ServiceFactory {
private ServiceFactory() {}
private static Service instance = new ServiceImpl();

public static Service getInstance() {
return instance;
}

public static void setInstance(Service service) {
instance = service;
}

}

4. 使用了工厂模式后,测试类的实现
public class Client {

public void test(){
Service service = ServiceFactory.getInstance();
service.go();

//跟上面有什么不同?
}
}

5. 对客户类进行测试的类
public void testClient() {
Service previous = ServiceFactory.getInstance();
try {
Client client = new Client();
client.test();
//what be printed?

final MockService mock = new MockService();
ServiceFactory.setInstance(mock);
client = new Client();
client.test();
//what be printed?
}
finally {
//must exists?
ServiceFactory.setInstance(previous);
}
}

6. 手工方式注入客户类,以及对客户类的测试
public class Client {
private final Service service;

public Client(Service service) {
this.service = service;
}

public void test() {
service.go();
}
}

public void testClient() {
MockService mock = new MockService();
Client client = new Client(mock);
client.test();
}

7. Guice 的实现方式
首先实现 Module,将服务类与要注入的测试类绑定
public class MyModule implements Module {
public void configure(Binder binder) {
binder.bind(Service.class)
.to(ServiceImpl.class)
.in(Scopes.SINGLETON);
}
}

//客户类中需要表明哪里需要注入
public class Client {
private final Service service;

@Inject
public Client(Service service) {
this.service = service;
}

public void test() {
service.go();
}
}

8. 测试类
public void testClient() {
Injector injector = Guice.createInjector(new MyModule());
Client client= injector.getInstance(Client.class);
client.test();
}

没有评论: