首页

源码搜藏网

首页 > 开发教程 > 软件设计 >

深度理解依赖注入

创建时间:2013-05-06 14:53  

1.依赖在哪里
   老马举了一个小例子,是开发一个电影列举器(MovieList),这个电影列举器需要使用一个电影查找器(MovieFinder)提供的服务,伪码如下:

 1深度理解依赖注入/*服务的接口*/
 2深度理解依赖注入public interface MovieFinder {
 3深度理解依赖注入    ArrayList findAll();
 4深度理解依赖注入}

 5深度理解依赖注入
 6深度理解依赖注入/*服务的消费者*/
 7深度理解依赖注入class MovieLister
 8深度理解依赖注入{
 9深度理解依赖注入    public Movie[] moviesDirectedBy(String arg) {
10深度理解依赖注入        List allMovies = finder.findAll();
11深度理解依赖注入        for (Iterator it = allMovies.iterator(); it.hasNext();) {
12深度理解依赖注入            Movie movie = (Movie) it.next();
13深度理解依赖注入            if (!movie.getDirector().equals(arg)) it.remove();
14深度理解依赖注入        }

15深度理解依赖注入        return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
16深度理解依赖注入    }

17深度理解依赖注入
18深度理解依赖注入    /*消费者内部包含一个将指向具体服务类型的实体对象*/
19深度理解依赖注入    private MovieFinder finder;
20深度理解依赖注入    /*消费者需要在某一个时刻去实例化具体的服务。这是我们要解耦的关键所在,
21深度理解依赖注入     *因为这样的处理方式造成了服务消费者和服务提供者的强耦合关系(这种耦合是在编译期就确定下来的)。
22深度理解依赖注入     **/

23深度理解依赖注入    public MovieLister() {
24深度理解依赖注入        finder = new ColonDelimitedMovieFinder("movies1.txt");
25深度理解依赖注入    }

26深度理解依赖注入}


从上面代码的注释中可以看到,MovieLister和ColonDelimitedMovieFinder(这可以使任意一个实现了MovieFinder接口的类型)之间存在强耦合关系,如下图所示:
深度理解依赖注入图1
这使得MovieList很难作为一个成熟的组件去发布,因为在不同的应用环境中(包括同一套软件系统被不同用户使用的时候),它所要依赖的电影查找器可能是千差万别的。所以,为了能实现真正的基于组件的开发,必须有一种机制能同时满足下面两个要求:
 (1)解除MovieList对具体MoveFinder类型的强依赖(编译期依赖)。
 (2)在运行的时候为MovieList提供正确的MovieFinder类型的实例。
   换句话说,就是在运行的时候才产生MovieList和MovieFinder之间的依赖关系(把这种依赖关系在一个合适的时候“注入”运行时),这恐怕就是Dependency Injection这个术语的由来。再换句话说,我们提到过解除强依赖,这并不是说MovieList和MovieFinder之间的依赖关系不存在了,事实上MovieList无论如何也需要某类MovieFinder提供的服务,我们只是把这种依赖的建立时间推后了,从编译器推迟到运行时了。
   依赖关系在OO程序中是广泛存在的,只要A类型中用到了B类型实例,A就依赖于B。前面笔者谈到的内容是把概念抽象到了服务使用者和服务提供者的角度,这也符合现在SOA的设计思路。从另一种抽象方式上来看,可以把MovieList看成我们要构建的主系统,而MovieFinder是系统中的plugin,主系统并不强依赖于任何一个插件,但一旦插件被加载,主系统就应该可以准确调用适当插件的功能。
   其实不管是面向服务的编程模式,还是基于插件的框架式编程,为了实现松耦合(服务调用者和提供者之间的or框架和插件之间的),都需要在必要的位置实现面向接口编程,在此基础之上,还应该有一种方便的机制实现具体类型之间的运行时绑定,这就是DI所要解决的问题。

继续>>下一页 [第1页][第2页][第3页][第4页] 2 0   标签: 设计模式依赖注入DI   
上一篇:大话权限设计
下一篇:OO真经——关于面向对象的哲学体系及科学体系的探讨(上)

相关内容

热门推荐