QQ客服热线
首页 > 信息资讯 > 技术专栏

技术专栏

为什么要用IOC
2013年8月29日
摘要: 控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题。 控制反转还有一个名字叫做依赖注入(Dependency Injection)。简称DI。

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容器是一个可复用的类管理工具, 可以很方便的引入到项目中, 通过向其中简单的注册需要被管理的类后, 他便能管理类和他们之间的关系. 这样避免了大量的工厂出现, 更进一步的减少了代码量, 提高了项目的扩展维护性.

来自TCNET 转载请保留www.nbtcnet.com

返回列表