读书人

(转载)关于IoC的引见

发布时间: 2012-08-29 08:40:14 作者: rapoo

(转载)关于IoC的介绍

IoC即Inversion of Control,控制反转。它不是一种编程技术,而是一种设计模式。利用它,可以促进应用程序组件或类之间的松散耦合。一般的情况下,我们需要自己创建对象的实例,比如在Computer类中创建一个打印机的实例:

1Printer printer = new DellPrinter();//创建一个戴尔打印机的实例
如果使用IoC,我们则不必再自己创建类的实例,而是将创建对象的任务交给IoC容器去做。这样,我们在使用某个对象的时候,就可以直接从容器中获取一个实例。就像一个好莱坞的原则一样“Don't call me.I'll call you!”,容器会在合适的时候创建它。我们就像不必考虑对象的销毁一样,也可以不必考虑对象的创建,这就是控制反转。
这样做有什么好处呢?在上面的例子中,我们创建为我们的电脑安装了一个戴尔打印机(创建一个戴尔打印机类的实例)。可是如果有一天,我们系统要升级了,需要使用惠普的打印机。这时,由于我们把打印机已经“固化”到电脑中了(打印机和电脑的耦合很高),要更换打印机,就不得不先拆开电脑,从主板中卸下打印机,再安装新的打印机(修改Computer类的源代码,然后重新编译,重新部署)。可以看到,这是一个计算机专家才能完成的任务,对于一个对计算机不是很了解的人来说,这将会是一场噩梦。那么如何解决这个问题呢?办法之一就是我们把打印机抽象成一个接口:


1 public interface Printer {
2 public void print();
3 }

这样各个厂商在生产打印机的时候,就只是需要实现这个接口所定义的功能就行了。就像我们在电脑上做一个专门的打印机模块,需要的时候卸掉原来的模块,再安装上新型号就的打印机可以了,前提是新的模块必须和以前的有一样的功能和调用接口。在电脑中变成了这样:




1 Printer printer ; // 提供一个打印机的接口
2 // 提供一个安装打印机的方法
3 public void setPrinter(Printer printer) {
4 this .printer = printer;
5 }
6
这样看似很好的解决了上述问题。但是实际上电脑(Computer)和打印机(Printer)之间的耦合性仍然很高:打印机的代码写入了电脑中,我们不得不在使用之前先调SetPrinter方法为电脑“安装”打印机,但是电脑使用者仅仅想使用打印机而已,可是这里他却不得不做安装打印机的工作。

这种依赖关系在“分离关注”的思想下是无法忍耐的,于是产生了新的模式,即控制反转( IoC )。使用这种方式,电脑 (Computer) 只是需要提供一个打印机 (Printer) 的“属性”和安装打印机的“渠道”。如果需要(当需要使用打印任务时), IoC 容器会在合适的时候自动为电脑注入(安装)打印机。这就好像我们请了个网管,我们要使用打印机的时候,可以直接告诉网管“我需要一个惠普打印机 ”,然后网管就自动的找到打印机并安装好,我们就可以使用它了。这样电脑使用者就可以完全不必关心打印机而只需使用它就行了。代码如下:

1 public class Computer {
2 private Printer printer;
3 public Print() {
4 printer.print();
5 }
6 public Printer getPrinter() {
7 return printer;
8 }
9 public void setPrinter(Printer printer) {
10 this .printer = printer;
11 }
12 }


1 < bean id ="Computer" class ="com.Computer" >
2 < property name ="printer" ref ="Printer" />
3 </ bean >
4

Spring 框架为我们提供了一个优秀的IoC容器。我们只是需要在它的配置文件中指明我们需要那个类的实例,这个类在那里,Spring的IoC容器会在合适的时候自动的为我们注入这个类的实例。从而我们可以完全不必考虑对象的创建工作,还可以实现应用程序各个组件的“即插即用”,而不需要修改源代码。

Spring提供呢多种配置文件的形式,但是推荐使用xml配置文件来驱动应用,尽管它也支持.properties文件和数据库的配置形式。

读书人网 >软件架构设计

热点推荐