[转帖]浅谈IOC--说清楚IOC是什么

Need Study
https://www.cnblogs.com/DebugLZQ/archive/2013/06/05/3107957.html

  

博文目录

1.IOC的理论背景

2.什么是IOC

3.IOC也叫依赖注入(DI)

4.IOC的优缺点

5.IOC容器的技术剖析

6.IOC容器的一些产品

7.参考博文

本文旨在用语言(非代码)说清楚IOC到底是什么,没有什么高深的技术,园中的老牛、大虾们看到这里可以绕行了,以免浪费您宝贵的时间。IOC这个东西DebugLZQ早就想写了,但是出于对文章权威性的考虑(不能误人子弟- -!),本文主要内容来源于最近LZ看的一些国内外的关于IOC的博文、博问,所有引用到的文章,在参考博文中均已注明。

1.IOC的理论背景

我们知道在面向对象设计的软件系统中,它的底层都是由N个对象构成的,各个对象之间通过相互合作,最终实现系统地业务逻辑[1]。

  图1 软件系统中耦合的对象

  如果我们打开机械式手表的后盖,就会看到与上面类似的情形,各个齿轮分别带动时针、分针和秒针顺时针旋转,从而在表盘上产生正确的时间。图1中描述的就是这样的一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协同工作,共同完成某项任务。我们可以看到,在这样的齿轮组中,如果有一个齿轮出了问题,就可能会影响到整个齿轮组的正常运转。

  齿轮组中齿轮之间的啮合关系,与软件系统中对象之间的耦合关系非常相似。对象之间的耦合关系是无法避免的,也是必要的,这是协同工作的基础。现在,伴随着工业级应用的规模越来越庞大,对象之间的依赖关系也越来越复杂,经常会出现对象之间的多重依赖性关系,因此,架构师和设计师对于系统的分析和设计,将面临更大的挑战。对象之间耦合度过高的系统,必然会出现牵一发而动全身的情形。

  图2 对象之间的依赖关系

  耦合关系不仅会出现在对象与对象之间,也会出现在软件系统的各模块之间,以及软件系统和硬件系统之间。如何降低系统之间、模块之间和对象之间的耦合度,是软件工程永远追求的目标之一。为了解决对象之间的耦合度过高的问题,软件专家Michael Mattson 1996年提出了IOC理论,用来实现对象之间的“解耦”,目前这个理论已经被成功地应用到实践当中。

2.什么是IOC

  IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”。

  1996年,Michael Mattson在一篇有关探讨面向对象框架的文章中,首先提出了IOC 这个概念。对于面向对象设计及编程的基本思想,前面我们已经讲了很多了,不再赘述,简单来说就是把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。

  IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦。如下图:

图3 IOC解耦过程

  大家看到了吧,由于引进了中间位置的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有人把IOC容器比喻成“粘合剂”的由来。

  我们再来做个试验:把上图中间的IOC容器拿掉,然后再来看看这套系统:

图4 拿掉IOC容器后的系统

  我们现在看到的画面,就是我们要实现整个系统所需要完成的全部内容。这时候,A、B、C、D这4个对象之间已经没有了耦合关系,彼此毫无联系,这样的话,当你在实现A的时候,根本无须再去考虑B、C和D了,对象之间的依赖关系已经降低到了最低程度。所以,如果真能实现IOC容器,对于系统开发而言,这将是一件多么美好的事情,参与开发的每一成员只要实现自己的类就可以了,跟别人没有任何关系!

我们再来看看,控制反转(IOC)到底为什么要起这么个名字?我们来对比一下:

软件系统在没有引入IOC容器之前,如图1所示,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在自己手上。

软件系统在引入IOC容器之后,这种情形就完全改变了,如图3所示,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。

通过前后的对比,我们不难看出来:对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。

3.IOC也叫依赖注入(DI)

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

  所以,依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。

  学过IOC的人可能都看过Martin Fowler(老马,2004年post)的这篇文章:Inversion of Control Containers and the Dependency Injection pattern[2]。

  博客园的园友EagleFish(邢瑜琨)的文章: 深度理解依赖注入(Dependence Injection)[3]对老马那篇经典文章进行了解读。

   CSDN黄忠成的Inside ObjectBuilder[4]也是,不过他应该来自台湾省,用的是繁体,看不管繁体中文的,可以看园中的吕震宇博友的简体中文版[转]Object Builder Application Block[5] 。

4.IOC的优缺点

In my experience, IoC using the Spring container brought the following advantages[6]:

  • flexibility

    • changing the implementation class for a widely used interface is simpler (e.g. replace a mock web service by the production instance)
    • changing the retrieval strategy for a given class is simpler (e.g. moving a service from the classpath to the JNDI tree)
    • adding interceptors is easy and done in a single place (e.g. adding a caching interceptor to a JDBC-based DAO)
  • readability

    • the project has one unified and consistent component model and is not littered with factories (e.g. DAO factories)
    • the code is briefer and is not littered without dependency lookup code (e.g. calls to JNDI InitialContext)
  • testability

    • dependencies are easy to replace mocks when they‘re exposed through a constructor or setter
    • easier testing leads to more testing
    • more testing leads to better code quality, lower coupling, higher cohesion

  使用IOC框架产品能够给我们的开发过程带来很大的好处,但是也要充分认识引入IOC框架的缺点,做到心中有数,杜绝滥用框架[1]。

第一、软件系统中由于引入了第三方IOC容器,生成对象的步骤变得有些复杂,本来是两者之间的事情,又凭空多出一道手续,所以,我们在刚开始使用IOC框架的时候,会感觉系统变得不太直观。所以,引入了一个全新的框架,就会增加团队成员学习和认识的培训成本,并且在以后的运行维护中,还得让新加入者具备同样的知识体系。

第二、由于IOC容器生成对象是通过反射方式,在运行效率上有一定的损耗。如果你要追求运行效率的话,就必须对此进行权衡。

第三、具体到IOC框架产品(比如:Spring)来讲,需要进行大量的配制工作,比较繁琐,对于一些小的项目而言,客观上也可能加大一些工作成本。

第四、IOC框架产品本身的成熟度需要进行评估,如果引入一个不成熟的IOC框架产品,那么会影响到整个项目,所以这也是一个隐性的风险。

我们大体可以得出这样的结论:一些工作量不大的项目或者产品,不太适合使用IOC框架产品。另外,如果团队成员的知识能力欠缺,对于IOC框架产品缺乏深入的理解,也不要贸然引入。最后,特别强调运行效率的项目或者产品,也不太适合引入IOC框架产品,像WEB2.0网站就是这种情况。

5.IOC容器的技术剖析

  IOC中最基本的技术就是“反射(Reflection)”编程,目前.Net C#、Java和PHP5等语言均支持,其中PHP5的技术书籍中,有时候也被翻译成“映射”。有关反射的概念和用法,大家应该都很清楚,通俗来讲就是根据给出的类名(字符串方式)来动态地生成对象。这种编程方式可以让对象在生成时才决定到底是哪一种对象。反射的应用是很广泛的,很多的成熟的框架,比如象Java中的Hibernate、Spring框架,.Net中 NHibernate、Spring.Net框架都是把“反射”做为最基本的技术手段。

6.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已经被广泛应用于各种项目中。

  总之就是很多很多,不甚枚举.....

7.参考博文

[1] 架构师之路(39)---IoC框架 ,王泽宾,CSDN, 2009.

[2] Inversion of Control Containers and the Dependency Injection pattern ,Martin Fowler,2004.

[3] 深度理解依赖注入(Dependence Injection),EagleFish(邢瑜琨), 博客园, 2007.

[4]Inside ObjectBuilder ,黄忠成, CSDN, 2006.

[5][转]Object Builder Application Block ,吕震宇,博客园, 2006.

[6]link

题外话:

看过的东西写整理一下写下来,一可以分享给各位博友,说不定对谁就有帮助;

二可以加深自己的认识,整理的过程本来就是一种认识的加深;

三是方便将来自己可能的查阅。

希望对你有帮助~

原文地址:https://www.cnblogs.com/jinanxiaolaohu/p/11052804.html

时间: 2024-10-11 13:10:27

[转帖]浅谈IOC--说清楚IOC是什么的相关文章

[]转帖] 浅谈Linux下的五种I/O模型

浅谈Linux下的五种I/O模型 https://www.cnblogs.com/chy2055/p/5220793.html  一.关于I/O模型的引出 我们都知道,为了OS的安全性等的考虑,进程是无法直接操作I/O设备的,其必须通过系统调用请求内核来协助完成I/O动作,而内核会为每个I/O设备维护一个buffer.如下图所示: 整个请求过程为: 用户进程发起请求,内核接受到请求后,从I/O设备中获取数据到buffer中,再将buffer中的数据copy到用户进程的地址空间,该用户进程获取到数

[转帖]浅谈响应式编程(Reactive Programming)

浅谈响应式编程(Reactive Programming) https://www.jianshu.com/p/1765f658200a 例子写的非常好呢. 0.9312018.02.14 21:22:16字数 1877阅读 9816 这是告别CSDN后第一次使用简书写IT类的博客,还在适应.最不适应的就是不能直接手输markdown语法标记.(好像原因是我没有切换编辑器) 什么是响应式编程(Reactive Programming) In computing, reactive program

浅谈IOC--说清楚IOC是什么

http://www.cnblogs.com/DebugLZQ/archive/2013/06/05/3107957.html 博文目录 1.IOC的理论背景 2.什么是IOC 3.IOC也叫依赖注入(DI) 4.IOC的优缺点 5.IOC容器的技术剖析 6.IOC容器的一些产品 7.参考博文 本文旨在用语言(非代码)说清楚IOC到底是什么,没有什么高深的技术,园中的老牛.大虾们看到这里可以绕行了,以免浪费您宝贵的时间.IOC这个东西DebugLZQ早就想写了,但是出于对文章权威性的考虑(不能误

浅谈对Spring Ioc的认识

原创链接:http://www.cnblogs.com/xdp-gacl/p/4249939.html 1.1.什么是IoC Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制.如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下: ●谁控制谁,控制什么:传统Java

浅谈Spring与IOC

1.什么是Spring Spring是一个开源的轻量级的应用开发框架,目的是为了简化企业级编程,降低各个模块之间的侵入性和耦合度 Spring 提供了IOC和AOP的功能,可以将组建的耦合度降低,便于日后的维护和升级,实现各个模块的组件化编程. 为什么要用Spring? Spring的本质是管理软件中的对象,就是创建对象和维护对象之间的关系 2.Spring容器 Spring容器的理解就是在Spring中,任何的Java和JavaBean都被当成Bean处理,这是bean都交给Spring容器管

My.Ioc 代码示例——谈一谈如何实现装饰器 (Decorator) 模式,兼谈如何扩展 My.Ioc

装饰器模式体现了一种“组合优于继承”的思想.当我们要动态为对象增加新功能时,装饰器模式往往是我们的好帮手. 很多后期出现的 Ioc 容器都为装饰器模式提供了支持,比如说 Autofac.在 My.Ioc 中,默认不提供装饰器支持,但我们可以自己进行扩展,以提供此项功能. using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using My.Ioc; u

浅谈Android保护技术__代码混淆

浅谈Android保护技术__代码混淆 代码混淆 代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为.将代码中的各种元素,如变量,函数,类的名字改写成无意义的名字.比如改写成单个字母,或是简短的无意义字母组合,甚至改写成"__"这样的符号,使得阅读的人无法根据名字猜测其用途.对于支持反射的语言,代码混淆有可能与反射发生冲突.代码混淆并不能真正阻止反向工程,只能增大其难度.因此,对于对安全性要求很高的场合,仅仅

蚂蚁变大象:浅谈常规网站是如何从小变大的(八)(转)

原文:http://blog.sina.com.cn/s/blog_6203dcd60100y1vi.html          [第十一阶段 :命名位置服务]   在前面我们不止一次提到了命名位置服务(Naming & Location Service).在不同的架构或者公司里面,这个名字往往不一样,比如,在java里面叫JNDI(Java Naming & Directory Interface),在有些地方可能会叫做资源位置系统(Resource Location System).

1.1浅谈Spring(一个叫春的框架)

如今各种Spring框架甚嚣尘上,但是终归还是属于spring的东西.所以在这里,个人谈一谈对spring的认识,笔者觉得掌握spring原理以及spring所涉及到的设计模式对我们具有极大的帮助.我们基于what ,why ,how来研究Spring. Spring是什么? Spring为什么? 如何使用Spring? 关于这三个问题可以先自行百度!!!针对这个3个问题提出以下几点. Spring有三大地方值得注意: 1.IOC容器 2.IOC控制反转和DI依赖注入 3.AOP面向切面编程 首