在java里,有很多方法可以把许多组件或者接口组成一个大的应用程序,Dendency Injection可以作为服务定位器的一种实现。
在j2ee的世界中有很多的开源的,活跃的框架实现了Inversion of control ,比如说 PicoContainer 和spring,探究一下他们表面下面的一些原则是很有意思的一件事。
说起组件可以找到上百本书和概念去介绍他,而我理解的是他是这样一种软件,他不会被轻易修改,作者并不能控制他的使用,系统用它的时候并不需要修改他们的代码。而一个服务跟组件一样也是被外界环境所调用,但是组件只是以一种短暂的方式被调用,(jar,dll),而服务是一种长久的(webservice,socket)。
class MovieLister...
public Movie[] moviesDirectedBy(String arg) {
List allMovies = finder.findAll();
for (Iterator it = allMovies.iterator(); it.hasNext();) {
Movie movie = (Movie) it.next();
if (!movie.getDirector().equals(arg)) it.remove();
}
return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
}
比如说这段代码,写的很不优雅,他让finder返回所有的电影,而去除之后自己筛选,我的真正的目的是让
一个美妙的movieDirectBy方法独立于电影如何被存储,所以所有的方法都指向一个借口finder,如何找取决于客户端的要求,
public interface MovieFinder {
List findAll();
}
这样就可以做到一定程度的解耦,
class MovieLister...
private MovieFinder finder;
public MovieLister() {
finder = new ColonDelimitedMovieFinder("movies1.txt");
}
比如说我想从一个文件中获取所有的movie,这样只要获取对应的专门处理这个的finder就可以了。
当然我可以从其他地方,如xml文件,web serivce,或者是SQL database都可以这样,比如说我的一个朋友也想
得到这些电影,但是我不知道他的电影是以哪种方式存储的,就不能在编译环境中加载这些类,这就是IOC出现的意义,
我感觉说spring的一大特性是IOC这根本算不上特性,因为这是所有轻量级框架都能够实现的。
ioc主要要考虑的就是怎么样把所需的组件是配到需要的调用者,di可以说是其中一种实现方式。
可以有constructor注入,setter注入,interface注入(比如说struts)等等,这里就不一一列举了。
除了DI我们还可以用service locator来查找相应的服务,他的中心思想是locator知道怎么样去hold住所有所需的服务,
就像他知道哪个finder去寻找影片。
我现在用单例来实现locator
class MovieLister...
MovieFinder finder = ServiceLocator.movieFinder();
class ServiceLocator...
public static MovieFinder movieFinder() {
return soleInstance.movieFinder;
}
private static ServiceLocator soleInstance;
private MovieFinder movieFinder;3
这只是这个locator的一个比较粗陋的实现,我们还可以把它设置成动态的,
class ServiceLocator...
private static ServiceLocator soleInstance;
public static void load(ServiceLocator arg) {
soleInstance = arg;
}
private Map services = new HashMap();
public static Object getService(String key){
return soleInstance.services.get(key);
}
public void loadService (String key, Object service) {
services.put(key, service);
}
个人感觉locator更像是一个工厂,选择色service locator还是DI完全取决于具体的情况。