素材牛VIP会员
如何理解IoC(Inversion of Control)?
 38***38  分类:Java代码  人气:2030  回帖:17  发布于6年前 收藏

RT,如何理解IoC(Inversion of Control)?如果能写个demo解释最好了。

 标签:rubyjavapythonphp

讨论这个帖子(17)垃圾回帖将一律封号处理……

Lv5 码农
Am***ze JS工程师 6年前#1

IoC,控制反转,把对XX的控制交给别人。
spring的DI就是你把new对象的工作交给spring。

Lv6 码匠
坐***来 技术总监 6年前#2

由于三言两语说不清楚,我写了一篇文章在这里,http://segmentfault.com/blog/zhaoyi/1190000002411255

Lv1 新人
Al***ay 职业无 6年前#3

依赖注入是控制反转的一种实现方式。

Lv3 码奴
gu***di 软件测试工程师 6年前#4

参考Spring Ioc容器
推荐阅读的文章
Inversion of Control Containers and the Dependency Injection pattern
InversionOfControl
自己动手写一个IoC工具

Lv1 新人
BO***OS 职业无 6年前#5

ioc 通俗一点的说,你把他想成一个大工厂,你问他要什么object,他就给你什么object,就是这么简单
他就像一个全局变量,在每个object里面的都可以访问到
你问他要什么object,他就给你什么object

Lv7 码师
亡***师 JS工程师 6年前#6

顧名思義吧,你寫出的程式是在操縱些什麼,比如說,給一些數據搬家,但是怎麼來指揮你的程式開始操控它要操控的對象呢?那麼你有要寫一些程式來做指(調)揮(用)你的程式,你定義一個規則,或者遵循一套規則,以便讓人來操控自身,其實這就是控制反轉,即,你是要把控制權交給別人的,仔細想想,其實這種反轉無處不在,更重要的是,怎麼讓別人來調用你的程式?需要約定接口,所以IoC也引導你更多的從面向接口方面考慮編程問題

Lv2 入门
th***as 职业无 6年前#7

我试着搜了一下,中文资料基本都把IoC(控制翻转)和DI(依赖注入)混为一谈,就连StackOverflow上的第一位答案也犯了同样的问题(幸好下面有高票的反对评论,否则我的世界观都快坏掉了)

控制翻转是代码复用的一种模式(注意不是设计模式)

一般(非IoC)的复用,通常是用户代码调用组件(任意形式的被复用的代码,本答案中统称为组件)。也就是用户代码解决“Why it works, What to do”,组件解决“How to do”,逻辑的入口是用户代码,

而控制翻转则是组件来调用用户代码,也就是组件解决“Why it works, When to do”,用户代码解决“What to do”,逻辑的入口是组件

下面是除了DI之外的控制翻转的例子

  • 接口/虚函数 组件调用接口/虚函数,具体由用户代码实现
  • 发布订阅(事件)模式 组件触发事件,用户代码订阅事件
  • 回调 用户代码写回调,组件来调用
  • 几乎所有能被称之为框架的东西 用户代码在规定的地方实现具体业务逻辑,剩下的框架负责
Lv4 码徒
想***儿 技术总监 6年前#8

举个例子,有一天,你去庆丰包子铺吃包子,进门后你首先需要找到点餐台在哪,然后告诉服务员你要什么,然后去领餐口领包子。这是以你为主的流程,一切都在你的掌握之下,但如果你不主动,就没有包子吃。

第二天,你去另一家高大上包子铺吃包子,这里,你只要坐下来说一句我要吃包子,就有服务员给你把包子端上来。这是以餐厅为主的流程,你不需要知道去哪点餐,去哪领包子。

如果把第一个流程作为“正”的话,那第二个流程就是“反”过来了。这就是所谓的IoC。不过,这个名字起的不太容易理解,因为正、反的概念是相对的,你也可以说第二个流程是正的。

把这个概念应用到GUI编程上,就是顺序执行和事件处理的区别。本来是你自己写的程序按顺序执行,例如第一步输入用户名,第二部输入密码,然后执行登录操作。使用了Windows或者其他图形界面框架后,就是由框架来负责运行你的程序,并且在用户输入了内容之后通知你的程序,你再去做处理。相对于顺序执行,事件驱动就是IoC的一种表现形式。

把这个概念应用到依赖管理上,假设你的程序需要引用另一个对象,本来你是需要在代码里创建这个对象,应用IoC模式后,你的程序不再去主动创建第三方对象,而是运行在一个容器或者框架里,例如Spring,然后等着Spring把你需要的对象创建好传递进来。这就是依赖注入(DI),IoC的另一种表现形式。

Lv4 码徒
朱***叶 UI设计师 6年前#9

本质是面向抽象编程,IOC描述的是特性,DI描述的具体实现方式,两者有共通的地方。可以这么理解:用DI实现具备IOC特性的框架,最终体现面向抽象编程的理念,增强系统的可扩性。
常见的“多态”就是面向抽象编程,比如:

Person person = new Male();
person.say();
person.run();
person.eat();

现在要把person指定为Female,则只需替换第一行即可:

Person person = new Female();

改动已经很少了,但仍可以做得更彻底一点:可不可以不更改现有代码就完成切换呢?答案就是"DI"。
撇开Spring不谈,咱们自己也完全可以实现一套最简化的类似功能:

Person person = SpringLike.getBeanFromConfig('person');

这行代码的意思就是,Person的实例是根据配置文件产生的,比如:

person=com.xx.Male

具体原理不赘述,大家耳熟能详。
回到上面那个问题,现在要把功能切换到Female,则只需更改配置文件即可:

person=com.xx.Female

将控制权进一步转移到配置文件,因而修改不涉及业务逻辑代码。
可以看出,“DI”是用更彻底的方式使用多态,在面向抽象编程这方面走得更远。"IOC"是面向抽象编程所体现出来的一个特性,本身和“DI”不冲突。

Lv7 码师
ha***23 职业无 6年前#10

IoC就是让框架为我们创建些东西。

App::bind('sms', function () {
   // Create a new SMS component.
   $sms = new SMSClient;
   $sms->setUsername('shauna');
   $sms->setPassword('1_5t341_c4t5!');
   // Return the created SMS component.
   return $sms;
});

据Clouser function特征,上面代的代码不会创建$sms对象。
$app->make('sms')的时候,$sms对象才被创建。所谓的反转大概就是按需创建吧。用的时候才触发创建,不是创建好了等着用。

因为程序员本身是农民工的一种,但是又想装的高大上一些,用以自赏,所以创建了这个很NB的术语,装的好像搞原子弹的。不用太在意。

上一页12下一页
 文明上网,理性发言!   😉 阿里云幸运券,戳我领取