我们常常看到说DI是解决OO中的耦合问题的。我一直有个疑惑,DI跟解耦有什么关系?
先说解耦。假如一个类成员变量是可以指向多种具体实现,那么,最简单的编程方式是:
class Animal{ Food food = new Grass(); } 或者 class Animal{ Food food; public Animal(){ food = new Grass(); } }
使用的时候,直接使用
Animal animal = new Animal();
就可以了。
但是,稍有编程常识的人都知道,为了保持程序的灵活性,需要对程序“解耦":
//使用构造函数 class Animal{ Food food; public Animal(Food food){ this.food = food; } }
或者
//使用setter class Animal{ Food food; public Animal(){} public void setFood(Food food){ this.food = food; } }
于是,我们可以很嗨皮地对新构建的Animal对象塞进任何食物了:
Food food = new Grass(); Animal animal = new Animal(food);
到目前为止,一切安好。但是问题还是来了:我们在使用一个对象的时候,除了生成这个对象的一个实例外,还要附加生成它所有的成员对象!如果成员对象很多,或者成员对象里面又各有自己的成员对象,子又有子子又有孙,子子孙孙无穷尽也,这项工作的工作量是相当可观的!
于是,喜欢偷懒的程序员开始琢磨:如果有一个容器或者工厂类之类的东西能够帮我完成这项费时费力的活,当我需要一个类的实例的时候,直接call一下这个容器,该有的就全都有了,该多好!
pico = new DefaultPicoContainer(); pico.addComponent(Animal.class); pico.addComponent(Food.class); //etc Animal animal = pico.getComponent(Animal.class);
这样,DI就诞生了!
最后一段代码来自于PicoContainer的示例代码:http://picocontainer.codehaus.org/constructor-injection.html