IOC理解

简介: 成功就是简单道理的深刻理解与灵活运用前不久,阿里大牛虾总在群里抛出一个问题:“从深层次讲解一下如何理解IOC,IOC和DI是一回事吗?”这个问题真是让人平静而又不平静平静源于此问题就像问中国人怎么使用筷子,天天使用筷子,难道还不会使用筷子?但又不平静,你能写出一份详细的说明书,让一个不会使用筷子的人按此说明成功地使用上筷子吗?

成功就是简单道理的深刻理解与灵活运用

前不久,阿里大牛虾总在群里抛出一个问题:“从深层次讲解一下如何理解IOC,IOC和DI是一回事吗?”

这个问题真是让人平静而又不平静

平静源于此问题就像问中国人怎么使用筷子,天天使用筷子,难道还不会使用筷子?

但又不平静,你能写出一份详细的说明书,让一个不会使用筷子的人按此说明成功地使用上筷子吗?


天天使用spring,是否还记得那些简单原理?现如今会写六种回字的你,还记得回的本意吗?

那些曾经刻骨铭心的记忆,你有多久没有想起了


IOC

不管是平时交流,还是面试,当谈谈spring时,除了api使用,最主要还是要聊聊IOC

Ioc—Inversion of Control,即“控制反转”

从语文的角度解析一下,如果“控制”当成一个动作,那就需要完善主语与宾语,也就是“谁”控制了“谁”;

“反转”:没有反转是什么情况,what反转,why反转,how反转

分两种情况讨论,1、没有IOC容器,2、有IOC容器

没有IOC容器

参与者

回答“谁”控制了“谁”中的两个“谁”

抽象讲:某个对象A控制了另一个某对象B

宏观讲 某个对象A可能就是应用程序,比如读取或者修改一个文件,那么此处的文件也就是某对象B了

微观讲,objectA 操作了 objectB,比如给objectB的属性赋值

从由内向外的角度 由两个参与者:某一对象(任意的对象类),以及对象外的各种资源(需要的其它对象、或者是对象需要的文件资源等等)

控制

常规情况下的应用程序,如果要在A里面使用C,当然是直接去创建C的对象,也就是说,是在A类中主动去获取所需要的外部资源C

image.png

A a = new AImpl(); 
C c = new CImpl(); 
a.setC(c);

当前类控制了一切:主动实例化、获取依赖、主动装配

这儿示例简单了点,一些项目会使用上Factory模式,让程序更面向接口,最小化变化,最大化地“开-闭”原则

但不管如何,还是会面临一些问题:

  1. 更换实现需要重新编译源代码
  2. 依赖变更很难更换实现、难于测试
  3. 耦合实例生产者和实例消费者

有IOC容器

引入IOC容器

参与者

除了对象与对象外的资源,增加了IOC容器

控制

引入IOC容器后,就不再是直接控制了,而是被动等待,等待IoC/DI的容器获取一个C的实例,然后反向的注入到A类中

image.png

此时,对象不再主动去new,而IoC容器来创建这些对象,即由Ioc容器来控制对象的创建;

再来看“谁”控制了“谁”?

IoC 容器控制了对象;控制什么?主要控制了外部资源获取(不只是对象包括比如文件等)

反转

A a = new AImpl(); 
C c = new CImpl(); 
a.setC(c);

还是看这段代码,包含了 主动实例化、获取依赖主动装配

根据【控制】,IOC做到了主动实例化、获取依赖;而【反转】体现在了主动装配这一点

传统应用程序是由我们自己在对象中主动控制去直接获取并set依赖对象,是为【正转】;

而【反转】则是由容器来帮忙创建及注入依赖对象;

为何是反转?

因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;

哪些方面反转了?

依赖对象的获取、装配被反转了


IOC总结

IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找

image.gifimage.png

传统关系转变成

image.png

IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了

这么小小的一个改变其实是编程思想的一个大进步,这样就有效的分离了对象和它所需要的外部资源,使得它们松散耦合,有利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活

DI

DI—Dependency Injection,即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。

通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。  

理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”

那我们来深入分析一下:

  • 谁依赖于谁:当然是应用程序依赖于IoC容器;  
  • 为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;  
  • 谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;  
  • 注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)

IOC VS DI

IoC和DI什么关系?

貌似是个仁者见仁的问题,有人认为两者是同一个东西,也有人认为是不同的概念;

摘抄一些见解


根据上面的讲述,应该能看出来,依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。


DI仅是用一个单独的对象(装配器)来装配对象之间的依赖关系,一般有setter、构造、接口注入等,与IOC不是一回事,仅是IOC依赖管理层面的东西


IOC是思想,DI是IOC的具体实现

也可看看鼻祖Martin Fowler的表述

As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection.

参考资料

Inversion of Control Containers and the Dependency Injection pattern

IOC是什么


目录
相关文章
|
3月前
|
设计模式 Java 容器
控制反转 (IoC)
【8月更文挑战第24天】
42 0
|
XML 开发框架 Java
Spring框架IoC控制反转
Spring是与2003年兴起的一个轻量级的Java开发框架,它是为了解决企业应用开发的复杂性而创建的。Spring的核心是控制反转(IOC)和面向切面编程(AOP)。Spring是可以在Java SE/EE中使用的轻量级开源框架。 Spring的主要作用就是为代码"解耦",降低代码间的耦合度。就是让对象和对象(模板和模板)之间关系不是使用代码关联,而是通过配置来说明。即在Spring中说明对象(模块)的关系。 Spring根据代码的功能特点,使用IOC降低业务对象之间耦合度。IOC使得主业务在相互调用过程中,不用再自己维护关系了,即不用再自己创建要使用的对象了,而是由Spring容器统一
81 2
|
Java Maven
SpringFrame-ioc 依赖注入
SpringFrame-ioc 依赖注入
|
JavaScript uml 容器
Ioc——控制反转
Ioc——控制反转
208 0
Ioc——控制反转
|
Oracle 架构师 Java
什么是IOC
什么是IOC
261 0
什么是IOC
|
自动驾驶 小程序 Java
什么是控制反转(IOC)?什么是依赖注入?
什么是控制反转(IOC)?什么是依赖注入?
什么是控制反转(IOC)?什么是依赖注入?
|
XML 存储 Java
|
Java 程序员 数据库
依赖注入IOC
依赖注入IOC
|
Java Spring
Ioc个人理解
IOC根据官方给的意思是依赖注入,说白了,调用类的方面不用"new 类名",而是在配置文件中配置后,然后新建一个工厂类,这样在工厂类中就可以直接调用了。下面是实现IOC的过程。
145 0
Ioc个人理解