浅谈IOC

IOC的理论背景

图1:传统系统中,对象之间相互引用的一幅图,在采用面向对象方法设计的软件系统中,它的底层的实现都是由n个对象所组成的,所有的对象通彼此之间的合作最终实现系统的业务逻辑,如果我们打开机械式手表的后盖,我们就会看到与图1类似的清形,各个齿轮分别带动时针、分针和秒针顺时针旋转,从而在表盘上产生正确的时间。这些齿轮相互耦合在一起,共同完成某项任务。在这样的齿轮组中,如果有一个齿轮出现一个问题,可能会影响到整个齿轮组的正常运转,齿轮组齿轮间的耦合关系与软件系统中对象之间的耦合关系非常相似。随着系统规模变大,对象之间依赖关系越来越复杂,架构师和设计师对系统的设计和分析面临更大的挑战,对象之间的耦合度过高的系统,必然会出现牵一发而动全身的情形,降低系统之间、模块之间、对象之间的耦合度是软件工程追求的目标。IOC理论的提出,就是为了解决对象之间耦合度过高的问题,实现对象之间的解耦。

图2 解耦的过程

IOC理论提出的观点大致是这样的:借助于第三方来实现对具有依赖关系的对象之间的解耦,对象之间没有了耦合关系。由于引进了第三方IOC容器,使得对象A、B、C、D之间没有了耦合关系,齿轮之间的传动全部依靠了第三方,全部对象的控制权全部交给了第三方IOC容器,IOC容器成了整个系统的关键核心,它起到了一种凝合剂i的作用,把系统中的所有对象凝合在一起发挥作用。

图3 理想的系统

这四个对象之间彼此毫无联系,这样在实现A的时候,无需去考虑B、C、和D,对象之间的依赖关系降低到了最低程度。  参与开发的每一位成员,只要实现自己的类就好了,跟别人没有任何关系。我们再来看看,控制反转到底为什么取这个名字。

软件系统在没有引入IOC容器之前,就像图1所示,对象A 依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须去创建对象B,或者是使用已经创建的B,无论是创建还是使用对象B,控制权全部都在自己手上,在软件系统引入了IOC以后,这种情形就完全改变了,如图2所示,由于IOC容器的加入,对象A和对象B失去了直接的联系,所以当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B,注入到对象A所需要的地方,通过前后的对比,不然看出,对象A获得依赖对象B的过程, 由主动行为变为了被动行为,控制权颠倒过来了,这个就是控制反转的名称的由来。哪些东西被反转了?获得依赖对象的过程被反转。获得依赖对象的过程由自身的管理变为了由IOC容器主动的注入。依赖注入(DI)其实是实现控制反转(IOC)的方式。

依赖注入DI

IOC的另外的名字叫做依赖注入(DI),所谓的依赖注入,就是由IOC容器再运行期间动态地将某种依赖注入到对象之中。所以,依赖注入(DI)和控制反转(IOC)是从不容的角度描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。

图4 电脑  和 外设都是对象,人起到IOC容器的作用

IOC容器就像一个对象制造工厂,你需要什么,它就会传送给你。你直接使用就可以,再也不用关心你是用的东西是如何生成的,最后如何销毁的,这一切都有IOC容器管理。再传统的实现中, 由程序内部代码来控制组件之间的关系,我们经常使用new关键字来实现两个组件之间关系的组合,这种方式会造成组件之间耦合,IOC很好的解决了这种问题,它将 实现组件间的关系 从程序内部提炼到了外部容器,也就是说由容器再运行期间将组件间的某种依赖关系动态地注入到组件中。

IOC好处

IOC在编程过程中不会对业务对象构成很强的侵入性,使用IOC之后,对象具有更好的可实行性,可重用性和可扩展性:

  • 降低组件之间的耦合度
  • 提高开发效率和产品质量
  • 同意标准,提高模块的复用性
  • 模块具有热插拔特性

举个例子:使用USB外部设备比使用电脑内置硬盘带来什么好处呢?第一:USB设备在插入主机之前,与电脑主机没有任何关系,只有被连接在一起后,才有关系,所以无论任何一方发生问题,都不会影响另一方,这在软件工程中就叫做可维护性,非常便于单元测试、调试程序和诊断故障。代码中的每个class都可以单独测试,彼此之间互不影响,只要保证自身的功能无误即可,这就是组件之间低耦合、无耦合带来的好处。 第二 USB和主机之间的无关性还带来了另外一个好处,生产USB和生产电脑的厂商可以是完全互不相干的两个人,他们各干各事,唯一需要遵守的是USB接口的标准,这种特性体现在软件开发过程中,好处很大,每一个开发团队的成员都只需要关心实现自身的业务逻辑,完全不用关心其他人的工作进度。你的任务可以单独测试也不依赖于别人的组件,每个人分工明确,效率提高。第三:提高了模块的复用性。同一个USB外部设备,可以插到任何支持USB的设备,可以插到电脑主机,可以插到DV机,USB外部设备可以被反复利用。我们可以把具有普遍性的、常用的组件独立出来,反复利用到项目中的其他部分或者其他项目,当然这也是面向对象的基本特征。第四:模块具有热插拔特性。IOC生成对象的方式,转为外置方式,也就是把对象生成放到了配置文件进行定义,这样当我们更换一个实现子类将会变得更加简单,只要修改配置文件就可以,完全具有热插拔的特性。(热插拔(hot-plugging或Hot Swap)即带电插拔,热插拔功能就是允许用户在不关闭系统,不切断电源的情况下取出和更换损坏的硬盘、电源或板卡等部件,从而提高了系统对灾难的及时恢复能力、扩展性和灵活性等,例如一些面向高端应用的磁盘镜像系统都可以提供磁盘的热插拔功能。)

IOC的通俗理解如下

  • IOC控制反转:说的是创建对象实例的控制权从代码控制剥离到IOC容器控制,实际就是你在XML文件当中的控制,侧重于原理
  • DI依赖注入:说的是再创建对象实例时,为这个对象注入属性值或其他对象实例,它侧重于实现。

【Spring】IOC的更多相关文章

  1. 【Spring】IOC容器注解汇总,你想要的都在这儿了!!

    写在前面 之前,我们在[Spring]专题中更新了不少关于Spring注解相关的文章,有些小伙伴反馈说,看历史文章的话比较零散,经常会忘记自己看到哪一篇了.当打开一篇新文章时,总感觉自己似乎是看到过了 ...

  2. 【Spring】 IOC Base

    一.关于容器 1. ApplicationContext和BeanFactory 2. 配置文件 XML方式 Java-configuration 方式 @Configuration 3. 初始化容器 ...

  3. 【Spring】IoC容器 - Spring Bean作用域Scope(含SpringCloud中的RefreshScope )

    前言 上一章学习了[依赖来源],本章主要讨论SpringBean的作用域,我们这里讨论的Bean的作用域,很大程度都是默认只讨论依赖来源为[Spring BeanDefinition]的作用域,因为在 ...

  4. 【Spring】IoC容器 - 依赖来源

    前言 上一篇文章已经学习了[依赖注入]相关的知识,这里详细的介绍一下[依赖来源]. 依赖来源 我们把依赖来源分为依赖查找的来源和依赖注入的来源分别讨论. 依赖查找的来源 1. Spring BeanD ...

  5. 【Spring】IoC容器 - 依赖注入

    前言 上一篇文章已经学习了[依赖查找]相关的知识,这里详细的介绍一下[依赖注入]. 依赖注入 - 分类 因为自己是基于小马哥的脉络来学习,并且很认可小马哥梳理的分类方式,下面按照小马哥思想为[依赖注入 ...

  6. 【Spring】IoC容器 - 依赖查找

    前言 上一篇文章已经学习了[IoC的主要实现策略]有2种: 1.依赖查找 2.依赖注入 这里稍加详细的介绍一下依赖查找 1.依赖查找的方式 依赖查找的方式可以以多种维度来划分: 1.按名称/类型/注解 ...

  7. 【Spring】IoC概述

    Spring框架的核心概念--IoC IoC IoC是Inversion of Control的简写,翻译成汉语就是"控制反转".IoC并不是一门技术,而是一种设计思想,在Spri ...

  8. 【Spring】AOP注解方式实现机制

    一.概述 二.@EnableAspectJAutoProxy 注解分析 三.分析AnnotationAwareAspectJAutoProxyCreator 四.执行流程 1. registerBea ...

  9. 【死磕 Spring】----- IOC 之解析 bean 标签:开启解析进程

    原文出自:http://cmsblogs.com import 标签解析完毕了,再看 Spring 中最复杂也是最重要的标签 bean 标签的解析过程. 在方法 parseDefaultElement ...

随机推荐

  1. 【Codeforces 484A】Bits

    [链接] 我是链接,点我呀:) [题意] 让你求出l~r当中二进制表示1的个数最多的数x [题解] 最多有64位 我们可以从l开始一直增大到r 怎么增大? 找到l的二进制表示当中0所在的位置 假设i这 ...

  2. POJ 1226 Substrings

    Substrings Time Limit: 1000ms Memory Limit: 10000KB This problem will be judged on PKU. Original ID: ...

  3. hdu 4670 树的分治-求点对的个数

    /* 树的分治 因为树的点权值可达到10^15,注意手动扩栈,还有int64 题意:给你一棵树,给你一些素数,给你每个点一个权值且每个权值均可由这些素数组成.现在定义任意任意两点的价值为他们路径上的权 ...

  4. 转载 - Struts2 拦截器详细配置过程

    出处:http://www.blogjava.net/zzzlyr/archive/2009/10/12/297998.html Struts2 拦截器详细配置过程 1:所有拦截器的超级接口Inter ...

  5. scrapy——中间件UserAgent代理

    pip install fake-useragent 使用说明:from fake_useragent import UserAgent# 实例化一个UserAgent对象ua = UserAgent ...

  6. codeforces gym 100357 H (DP 高精度)

    题目大意 有r*s张扑克牌,数字从1到 r,每种数字有s种颜色. 询问对于所有随机的d张牌,能选出c张组成顺子的概率和组成同花的概率. 解题分析 对于组成顺子的概率,令dp[i][j][k]表示一共选 ...

  7. N - Is It A Tree? 并查集

    A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one ...

  8. codevs——1530 大质数

    1530 大质数  时间限制: 1 s  空间限制: 1000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 小明因为没做作业而被数学老师罚站,之后数学老师 ...

  9. ubuntu 必備

    1.切换到Ubuntu gnome 经典桌面注销unity桌面环境,然后选择登录环境为“经典桌面”即可进入.若是你喜欢Unity,可是你的显卡不给力3D不支持,怎么办呢?安装Unity-2D:sudo ...

  10. Unity3D 怎样在安卓手机上播放视频

    曾经仅仅会在电脑上通过Unity3D播放视频,研究了下发现通过Unity3D在手机上播放视频也很easy.现介绍例如以下. void OnGUI()     {         if (GUI.But ...