下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

简单说说IOC是什么

作者:课课家教育     来源: http://www.kokojia.com点击数:3287发布时间: 2016-07-31 09:00:00

标签: IOC理论IOC优缺点IOC控制反转

大神带你学编程,欢迎选课

  学习Java框架的同学都会听过IOC,但是对于刚刚接触的朋友来说,可能并不太了解什么是IOC?在这里要说的是,在学习IOC之前你要明白的是IOC并不是一种技术而是一种思想。接下来本文会对IOC的理论、IOC的优缺点以及它为什么称控制反转作简单的介绍。

     IOC理论

   如果你打开机械手表的后盖,想一些精细一些的机械手表你会看到若干个齿轮在带动时针、分针以及秒针的运行。就如图中的所描述的,在一个齿轮组中,由这些独立的齿轮相互合在一起,协同工作,共同完成某项任务。但是一旦一个齿轮出现了问题就会波及整个齿轮组。

IOC比喻成手表齿轮

   而我们所知道的面向对象设计的软件系统中,它的底层就像齿轮组一样由若干个对象构成的,各个对象通过相互之间的合作,最终实现系统的业务逻辑。齿轮组中的齿轮间的啮合关系,和面向对象设计的软件系统中的对象之间的耦合非常相似。在软件系统中的耦合关系是无可避免的,这是协同工作的基础。耦合关系不仅仅只出现在对象于对象之间,也会出现在软件系统的模块之间,以及软硬件系统之间。而软件工程永远追求的目标是降低这些对象、模块、系统之间的耦合度。

   并且随着工业级应用的不断发展,系统中对象之间的依赖关系越来越复杂,经常会出现多重依赖性的关系。所以对于系统的分析和设计面临着更大的挑战和考验。不然对象耦合度太高的系统必定会出现牵一发而动全身的现象。

   所以为了解决高耦合度的问题,在1996年软件专家Michael Mattson提出了IOC理论用于实现对象之间的“解耦”并且成功的应用到了实践中。

  什么是IOC?(控制反转)

  IoC是Inversion of Control的缩写,有的翻译成“控制反转”,还有翻译成为“控制反向”或者“控制倒置”。它不是一种技术,而是一种思想。在java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。

  软件专家Michael Mattson在1996年首先在一篇有关探讨面向对象框架的文章中提出了IOC这个概念。简单来说就是把复杂的系统分解成可以相互合作的对象,在这些对象进行封装之后,就实现内部对外部的透明,这样就解决了问题的复杂程度。

  IOC的理论观点如图:

  图中表达的意思是,在把各个对象类进行封装之后,通过IOC容器来关联这些对象类。这样子对象与对象之间就是通过IOC进行联系,从而减少了对象与对象的直接关系。

  但是如果去掉了IOC容器之后对象与对象之间又会有了直接的关系。如图:

去掉IOC容器之后的系统

  为什么叫控制反转?

  谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

  为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

   我们可以进行对比:

   — 软件系统在没有引入IoC容器之前,对象A依赖对象B,那么A对象在实例化或者运行到某一点的时候,自己必须主动创建对象B或者使用已经创建好的对象B,其中不管是创建还是使用已创建的对象B,控制权都在我们自己手上。

   — 如果软件系统引入了Ioc容器之后,对象A和对象B之间失去了直接联系,所以,当对象A实例化和运行时,如果需要对象B的话,IoC容器会主动创建一个对象B注入到对象A所需要的地方。

   — 通过前面的对比,可以看到对象A获得依赖对象B的过程,由主动行为变成了被动行为,即把创建对象交给了IoC容器处理,控制权颠倒过来了,这就是控制反转。

  IOC也可以叫做依赖注入(DI)

   在2004年的时候,Martin Fowler探讨了同一个问题,既然IOC是控制反转,那么到底是“哪些方面的控制被反转了呢?”上文我们已经解释过了,得出的答案就是“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。他的这个答案,实际上给出了实现IOC的方法:注入。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。

   也就可以说,IOC和DI只是从不同的角度去描述同一件事情。通过引入IOC容器利用依赖关系注入实现对象之间的解耦。由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IOC 而言,“依赖注入”明确描述了“被注入对象依赖IOC容器配置依赖对象”。

  IOC的优点以及缺点

   灵活性

    可以简单的改变一个广泛使用的接口的实现类

    改变检索策略对于一个给定的类更简单(例如移动服务从类路径的JNDI树)

    在一个地方调价拦截器是简单的(如添加一个拦截器与基于jdbc的缓存DAO)

  可读性

   这些项目有一个统一的组件模型,而不是零散的。

   代码更加简单。

  可测试性

   当他们通过构造函数的时候依赖关系很容易取代。

   可维护性比较好并且便于进行单元测试

   更多的测试会导致更高的代码质量

  虽然说使用IOC容器可以给我们的开发带来很多的好处,但是也要知道IOC框架的缺点

   1.由于软件系统中引入了IOC容器,会使得生成对象的步骤变得复杂,因为本来只是两者之间的事情现在又多了一道程序。

   2.因为IOC容器生成对象是通过反射的方式,所以在运行效率上有一定的的减少。

   3.对于IOC框架产品来说,需要大量的配置工作,比较麻烦。

   4.如果引入一个不成熟的IOC框架产品有可能会影响到整个项目的运行,这是IOC中一个隐藏的风险。

  IOC容器技术

   在IOC中最基本的技术就是“反射”。关于反射的概念,简单来说就是根据给出的类名来动态的生成对象。这种编程方式可以让对象决定到底是哪一种对象。目前.NET C#、Java和php5等语言均支持,很多的成熟的框架,比如象Java中的Hibernate、spring框架,.Net中 NHibernate、Spring.Net框架都是把“反射”做为最基本的技术手段。

  IOC容器中的一些产品

  Sun ONE技术体系下的IOC容器有:

   轻量级的有Spring、Guice、Pico Container、Avalon、HiveMind;

   重量级的有EJB;

   不轻不重的有JBoss,Jdon等等。

   Spring框架作为Java开发中SSH(Struts、Spring、Hibernate)三剑客之一,大中小项目中都有使用,非常成熟,应用广泛,EJB在关键性的工业级项目中也被使用,比如某些电信业务。

  .Net技术体系下的IOC容器有:Spring.Net、Castle等等。

   Spring.Net是从Java的Spring移植过来的IOC容器,Castle的IOC容器就是Windsor部分。它们均是轻量级的框架,比较成熟,其中Spring.Net已经被广泛应用于各种项目中。

      刚刚学习的朋友可能对与IOC和DI两个概念分不清,在本文中简单的介绍了一下两者以及之间的联系。如果有需要详细了解的朋友可以去网上查找。总的来说IOC框架的作用还有很好的,特别是对于大型的软件系统之中。希望本文能对有所疑问的朋友有所帮助。

赞(1)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程