关键词:factory pattern , Dependency Injection(DI), Guice(pronounced “juice” )
参考:
【1】维基DI :http://en.wikipedia.org/wiki/Dependency_injection
【2】一篇博文:http://www.blogjava.net/xylz/archive/2009/xylz/archive/2009/12/23/307092.html
阐述问题:Why Guice exist && What is DI
正文:
Listing1-1code写的是厨子需要的一个随机产生祝福语的功能。
Listing1-2code是使用GOF factory pattern
这里 service就是 FortuneService,它被定义成了一个接口。
FortuneServiceImpl是它的一个实现类。
这里client就是Chef
//Listing1-1
public interface FortuneService { String randomFortune(); } public class FortuneServiceImpl implements FortuneService { private static final List<String> MESSAGES = Arrays.asList( "Today you will have some refreshing juice.", "Larry just bought your company." ); public String randomFortune() { return MESSAGES.get(new Random().nextInt(MESSAGES.size())); } }
//Listing 1-2 public class Chef { private FortuneService fortuneService; public Chef() { this.fortuneService = FortuneServiceFactory.getFortuneService(); } public void makeFortuneCookie() { new FortuneCookie(fortuneService.randomFortune()); } } public class FortuneServiceFactory { private FortuneServiceFactory() {} private static FortuneService fortuneService = new FortuneServiceImpl(); public static FortuneService getFortuneService() { return fortuneService; } public static void setFortuneService(FortuneService mockFortuneService) { fortuneService = mockFortuneService; } }代码1-3就是对上面的一个测试代码,但这出现了两个问题
问题1:我们得先实例化一个FortuneService使用FortuneServiceFactory.setFortuneService()注入到FortuneServiceFactory中
问题2:另外我们需要在finally中恢复原来FortuneService的值,不然就有数据污染。
于是,DI就出现了,DI是如何解决这个问题的呢
key sentence也就是DI的主要思想是 :
instead of pulling your dependencies in(例如代码1-3), you opt toreceivethem from someplace
[思想引用自好莱坞:don‘t call us,we‘ll call u]
DI的优势P14页列了几条,但是没特别明白,为什么尽量不使用static方法
再往下走
Listing1-4就是使用了DI修改过的chef,与1-2相比,1-4的chef采用构造函数注入的方法,将FortuneService作为参数进行初始化。
Listing1-5就是对应的使用DI思想的unit test,代码简练很多,并且没有了static方法,也不用在finally内部做数据恢复。
但是问题还是存在的,既然chef构造函数有一个FortuneService作为参数,于是我们在实例一个chef之前需要实例一个FortuneService。这是我理解代码1-6是什么意思。
于是,GUICE就出现了,GUICE是如何解决这个问题的呢
Guice可以不使用factory而是使用几个简单的配置就完成了注入工作,在需要注入的地方书写@Inject
Listing1-7就是展示如何使用inject语法就加了一行@Inject
Listing1-8是对应的test,没有变化
然后剩下就是define a module告诉哪里需要implementation工作
Listing 1-9展示了其中一种方法,语法非常好读。
最后就是总结:目的就是写出maintanable、好测试的代码,又要摆脱工厂模式、又要DI巴拉巴拉
hapter 1: Setting the Stage,布布扣,bubuko.com
原文地址:http://blog.csdn.net/ict_100/article/details/38229281