转至:http://hi.baidu.com/lewutian
1.IOC本质
Ioc(Inversion of Control)中文译名控制反转
IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制。这称为控制反转
比如:
你编写了一个业务逻辑类,但是现在必须给这个类中的所有或部分方法添加操作日志
不用IOC:
修改精力逻辑类的源代码,在所有或部分方法中添加日志操作代码
用IOC:
编写一个日志类和配置文件,通过IOC技术将日志类和业务逻辑类关联起来,实现日志记录功能
2.不用IOC面临的问题
比如,现在准备做一个业务操作类service,其代码实现如下:
Interface IService{
go();
}
public Service implements IService{
public void go() {
...
}
}
实现Service实例化的几种方式及分析:
第一种方式
Service service = new Service();
这样个方式非常直观, 但是维护性差,由于我们不能保证目前设计的正确性,所以,维护Service这个类时
如果这个类永远是给自己用的,那么自己多花些时间修改以前的代码,也没什么大不了,自己的种的苦果自己吃
如果作为公司的产品发布出去,给别人用了,那么,必须在保证该类所有的方法或属性与之前保持一致的基础上,再新增属性和方法,这个可就要命了,既要承认以前的设计和方法的功能有错误,又不能改正以前的错误。
所以现在多用第二种方法,只是发布接口里有几个方法,分别完成什么功能,接口一旦发布,是不能修改了。但如果具体的类有bug,可以重新发布具体的类,并且一定程序上屏蔽了具体类的内部实现。
第二种
IService service = new Service();
这样的方式一定程序上解决了和具体实现类耦合问题,但是还是面临着新的问题:
如果实现这个接口的具体类的类名变了,怎么办?
比如:现在2.0版本,Service.java变成了Service2.java
还是必须修改源代码。能不能当具体实现类的类名变化时,也不用修改源代码?那就得用第三种方式
第三种
IService service = ServiceFactory.Create();
工厂模式, 在Ioc容器出现以前被广泛应用于各种项目中, 甚至有这样的说法, 没有工厂的项目就不是好项目, 虽然有点偏激但却有一定道理. 以ServiceFactory.Create()来推迟了类的实例化, 这样看起来无论声明和实例化都脱离了对具体类的依赖, 但具体的类终究还是要实例化, 在哪里呢? 看看工厂的实现, 在ServiceFactory.Create()中有2中实现方案.
方案一
直接return new Service(); 这效果和上一种方式没啥本质区别了, 到头来换了具体实现类还得修改代码.
方案二
读取配置文件中的信息, 用反射来实例化组件, 彻底的把具体实现类的信息从代码中剥离到了配置文件中, 更换具体实现类时仅需要修改配置文件. 接口终于完全的发挥出了他的威力, 但这种方式造成大量不统一的工厂产生, 而具体实现类之间常会有着各种不同的依赖关系, 使得工厂的复杂度大大增加, 实现与管理这些工厂又成了新的问题, Ioc容器就在这样的需求下出现了.
第四种
IService service= CommonService.Container.Resolve<IService>();
看起来和通过工厂获取实例差不多, 但 CommonService.Container是简易包装的一个Ioc容器,现在你只需要知道我从容器中来获取类的实例. Ioc容器是一个可复用的类管理工具, 可以很方便的引入到项目中, 通过向其中简单的注册需要被管理的类后, 他便能管理类和他们之间的关系. 这样避免了大量的工厂出现, 更进一步的减少了代码量, 提高了项目的扩展维护性.
参考文献
1.simonw. Ioc容器应用浅析. http://www.cnblogs.com/simonw/archive/2006/10/06/518342.html