控制反转(IoC)与依赖注入(DI)(ioc控制反转和di依赖注入)
toqiye 2024-10-14 17:31 9 浏览 0 评论
控制反转的英文全称Inversion of Control,简称IoC,依赖注入的全称Dependency Injection,简称DI。控制反转与依赖注入这两个概念不好理解,尤其是刚接触这两个概念的时候。
有人认为依赖注入是控制反转的别名,也有人认为依赖注入是控制反转的一种方式。
概念的发展与演进
IoC这个概念是最早出现在Ralph E. Johnson & Brian Foote (June–July 1988)的文章《Designing Reusable Classes》中,原文片段:
One important characteristic of a framework is that the methods defined by the user to tailor the framework will often be called from within the framework itself, rather than from the user's application code. The framework often plays the role of the main program in coordinating and sequencing application activity. This inversion of control gives frameworks the power to serve as extensible skeletons. The methods supplied by the user tailor the generic algorithms defined in the framework for a particular application.(框架的一个重要特征是,用户为定制框架而定义的方法通常会在框架内部调用,而不是从用户的应用程序代码中调用。框架通常在协调和排序应用程序活动中扮演主程序的角色。这种控制的反转使框架能够作为可扩展的骨架。用户提供的方法为特定应用程序定制(改写)了框架中定义的通用算法。)
虽然IoC这一概念在《Designing Reusable Classes》一文中出现,但是文中并未给出比较具体的定义。
Michael Mattson于1996年在其发表的文章《Object-Oriented Frameworks, A survey of methodological issues》中首次给出了比较具体的描述,我认为这还不能称作给IoC下定义:
The major difference between an object-oriented framework and a class library is that the framework calls the application code. Normally the application code calls the class library. This inversion of control is sometimes named the Hollywood principle, Do not call us, we call You .
(面向对象框架和类库之间的主要区别是框架调用应用程序代码。通常应用程序代码调用类库。这种控制的反转有时被称为好莱坞原则,不要给我们打电话,我们会给你打电话的)
通过这样一段简短的表述我们知道了,为什么叫“反转”,之所以能看出这是“反转”取决于参照物,即应用程序代码调用类库。而应用IoC模式后,变成类库(框架)调用应用程序代码了,这就是“反转”。这有什么好处呢??我们最先想到的可能就是提高代码的复用率,这么回答显得太笼统,有一种人云亦云的感觉。其实在《Designing Reusable Classes》这篇文章中已经为我们概括了:使框架能够作为可扩展的骨架,即框架定义了一个通用的算法,但是当某个特定的应用程序需要一个定制化的算法时,用户可以在应用程序中实现这个定制化的算法,这样看来,框架的这部分功能就像一个通用的模板一样,只给出大体的实现方案,而不给出具体的细节描述,用户可以针对不同的场景完善细节。
我们在仔细剖析那句话:This inversion of control is sometimes named the Hollywood principle。这句话似乎应该理解为IoC有时被称为Hollywood principle,但是有时不能称为Hollywood principle,那么什么时候不能被称为Hollywood principle,这个文中没有指明,为了探究这个问题。我们查查Hollywood principle的定义是什么。
我们到wiki查查Hollywood principle,发现了相当有趣的事情,检索到的词条居然是关于Inversion of control的。注意到词条下的一行字了吗?
From Wikipedia, the free encyclopedia
(Redirected from Hollywood principle)
看来业界将这两个词划等号了,这里就不深究他们的不同了,毕竟我们的目的是在辨析概念的基础上学习如何正确的运用这些原则。
业界比较著名的关于IoC的文章当属Martin Fowler的文章。
Martin Fowler在他的文章《Inversion of Control》中提到:
Inversion of Control is a key part of what makes a framework different to a library. A library is essentially a set of functions that you can call, these days usually organized into classes. Each call does some work and returns control to the client.(控制反转是框架不同于库的关键。库本质上是一组你可以调用的函数,现在通常被组织成类。每个调用都做一些工作并将控制权返回给客户端)
There is some confusion these days over the meaning of inversion of control due to the rise of IoC containers; some people confuse the general principle here with the specific styles of inversion of control (such as dependency injection) that these containers use. The name is somewhat confusing (and ironic) since IoC containers are generally regarded as a competitor to EJB, yet EJB uses inversion of control just as much (if not more).(由于IoC容器的兴起,现在对控制反转的含义有一些混淆;有些人在这里混淆了一般原则和这些容器使用的特定类型的控制反转(例如依赖注入)。这个名称有些令人困惑(而且具有讽刺意味),因为IoC容器通常被视为EJB的竞争对手,然而EJB使用的控制反转同样多(如果不是更多的话)。)
Michael Mattson和Martin Fowler的文章中在阐述框架和类库之间区别时的表述不同,但都强调了控制反转是区分两者的关键。Michael Mattson指明了调用与被调用的关系,而Martin Fowler更像是对Michael Mattson那句话的补充:库的本质是什么。Martin Fowler还强调了调用的控制权归属问题。
Martin Fowler在文中提到了另一个重要概念,依赖注入(dependency injection),我们看一下依赖注入的定义:
In software engineering, dependency injection is a technique in which an object receives other objects that it depends on, called dependencies. Typically, the receiving object is called a client and the passed-in ('injected') object is called a service. The code that passes the service to the client is called the injector. Instead of the client specifying which service it will use, the injector tells the client what service to use. The 'injection' refers to the passing of a dependency (a service) into the client that uses it. (在软件工程中,依赖项注入是一种技术,在这种技术中,对象接收它所依赖的其他对象,称为依赖项。通常,接收对象的一方被称为客户端,传入(“注入”)的对象称为服务。将服务传递给客户端的代码称为注入器。不是客户端指定它将使用哪个服务,而是注入器告诉客户端要使用哪个服务。“注入”指的是将依赖(服务)传递给使用它的客户端)
看着这段定义,是不是觉得这就是控制反转的一种实现,或者说这就是控制反转的别名。能这样理解吗?Martin Fowler在他的另一篇文章中提到了DI。
Underlying these containers is a common pattern to how they perform the wiring, a concept they refer under the very generic name of "Inversion of Control". In this article I dig into how this pattern works, under the more specific name of "Dependency Injection", and contrast it with the Service Locator alternative.(在它们的背后有着同一个模式,这个模式决定了这些容器进行组件装配的方式。人们用一个非常通用名字来称呼这个模式:“控制反转”。在本文中,我将在更具体的名字“依赖注入”下,深入探索这个模式的工作原理,并将其与服务定位器模式作一个比较。)
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.(因此,我认为我们需要为这个模式取一个更具体的名称。控制反转是一个过于通用的术语,因此人们觉得它很难理解。因此,通过与多位IoC的拥护者大量讨论,我们确定了依赖注入这个名称。)
从这两段表述中可以看出,Martin Fowler和多位IoC的拥护者认为IoC与DI是对等的概念。他们认为Ioc更加泛化而难以理解。
我的世界
如果时间久了,这些概念很容易淡忘,为了不让自己忘记,我决定用自己的体验强化记忆。有可能你觉得我是在一本正经的胡说。
关于控制反转
人类社会有没有控制
参考
1.Ralph E. Johnson & Brian Foote (June–July 1988). "Designing Reusable Classes".Journal of Object-Oriented Programming, Volume 1, Number 2. Department of Computer Science University of Illinois at Urbana-Champaign. pp. 22–35. Retrieved 29 April 2014.(http://www.laputan.org/drc/drc.html)
2.Michael Mattsson (February 1996). "Object-Oriented Frameworks, A survey of methodological issues".(https://encyclopedia.thefreedictionary.com/Inversion+of+control)
3.Inversion of Control by Martin Fowler(https://martinfowler.com/bliki/InversionOfControl.html)
4.Inversion of Control Containers and the Dependency Injection Pattern by Martin Fowler
相关推荐
- 基于Python查找图像中最常见的颜色
-
如果我们能够得知道一幅图像中最多的颜色是什么的话,可以帮助我们解决很多实际问题。例如在农业领域中想确定水果的成熟度,我们可以通过检查水果的颜色是否落在特定范围内,来判断它们是否已经成熟。接下来我们将使...
- 出大要几次/圣彼得堡悖论
-
程序:fromrandomimportrandomdeffn():n=1whilerandom()<0.5:n+=1returnny=[fn()...
- 使用OpenCV测量图像中物体之间的距离
-
原文链接:https://www.pyimagesearch.com/2016/04/04/measuring-distance-between-objects-in-an-image-with-op...
- 让颜色更加饱满和有冲击力:图像颜色校正
-
大家拍照或图片时,获取会遇到图像颜色与实际颜色存在色差的现象。我们看一个标准色卡的图片:第一张图片就是有色差的图片,这种现象一般是相机或光线的原因造成的,我们可以通过标准色卡进行校正。第一张图片是有色...
- Python 数据分析 : 实例
-
1、构建矩阵生成4x4形式的矩阵,矩阵中的数据是1~10之间的随机数random_list=np.random.random(16)random_list=np.round(...
- 用这些免费开源的图标库,为你的项目画龙点睛
-
精致好看的图标能够为你的项目增色不少,今天我就整理了一期图标库精选系列,希望你可以从中找到自己喜欢的图标库。下面就跟我来一场视觉的盛宴,我会一一介绍GitHub上品牌、流行、极小,各具特色的免费精...
- ICON设计规范之图标尺寸
-
编辑导语:图标设计是UI设计中不可缺少的元素,它看似简单,但其实内含门道。本篇文章里,作者就对icon设计的相关知识和icon绘制方法做出经验介绍。如果你对icon设计也想要有所了解的话,那就点进来看...
- PHP开发必备VSCode插件(大全)
-
通用chinese(simplified...):简体中文语言包liveserverhtml:实时预览prettier-codeformatter:最流行的代码格式化插件...
- 增强用户体验:前端开发中HTML5和CSS3表格属性的应用与优化研究
-
摘要:本文探讨了在前端开发中HTML5和CSS3表格属性的应用与优化。首先介绍了HTML5中常用的表格元素和CSS3中丰富的表格样式属性,旨在帮助开发人员定制表格的外观和样式。其次,研究了表格结构的优...
- 产品经理小技术:图片素材随手找,原型设计快又好
-
数十万互联网从业者的共同关注!作者:牛冰峰博客:http://uxfeng.com/画图——这项古老而精细的做法,是一代代产品狗们得以传承的立足之本。草图、线框图、思维导图、PPT插图、数据汇报图表、...
- MAUI Blazor 项目实战 - 从0到1轻松构建多平台应用UI
-
前言最近在项目中尝鲜了MAUI,总体感受下来还是挺不错的,优缺点并存,但是瑕不掩瑜,目前随着.Net版本的迭代升级对它的支持也越来越友好,相信未来可期!感兴趣的朋友欢迎关注。文章中如有不妥的地方,也请...
- webstorm常用的插件
-
1、AtomMaterialIcons推荐原因:这款插件不仅...
- 「智能家居」自动化平台nodered第三方节点dashboard的使用
-
自带节点库讲完了,开始说说第三方节点库dashboard,该库提供另一个可配置的UI页面,可以配置一些表单元素,以及图表。先来看一下别人使用dashboard制作的面板吧,是不是很漂亮。接下来我们一...
- 「炫丽」从0开始做一个WPF+Blazor对话小程序
-
大家好,我是沙漠尽头的狼。...
- MAUI使用Masa blazor组件库
-
上一篇(点击阅读)我们实现了UI在Web端(BlazorServer/Wasm)和客户端(Windows/macOS/Android/iOS)共享,这篇我加上MasaBlazor组件库的引用,并...
你 发表评论:
欢迎- 一周热门
-
-
如何评估预测值与真实值之间的匹配质量
-
如何解决npm安装依赖报错ERESOLVE unable to resolve dependency tree
-
超详细的cmder工具介绍及功能、快捷键说明
-
畅网 N5105 四口 2.5G 小主机安装 WIN10 对比 WIN11 跑分
-
常见面试第三题之Activity的几种启动模式介绍
-
软件推荐丨gocron —— 定时任务管理系统
-
一分钟带你认识了解电信光猫(电信光猫有什么用途)
-
聊聊C++20最大的变革之一 —— Coroutine,看不懂你打我(一)
-
硬核!Rust异步编程方式重大升级:新版Tokio如何提升10倍性能详解
-
Vite 4.0 正式发布(vite版本)
-
- 最近发表
- 标签列表
-
- systemproperties (65)
- npm版本管理 (61)
- localhost:15672 (59)
- materialtheme (86)
- node-ssh (68)
- 图床搭建 (62)
- vue3addeventlistener (60)
- mybatisselectone (78)
- css圆形进度条 (69)
- androidble蓝牙开发 (62)
- android-gif-drawable (60)
- appender-ref (64)
- springbootmockito (68)
- css边框渐变色和圆角 (58)
- gsonfastjson (59)
- 依赖注入的方式 (62)
- cookie跨域共享 (63)
- easyexcel导出图片 (77)
- dp数组 (61)
- js获取兄弟节点 (68)
- sysctl-a (60)
- java知音 (58)
- window.target (62)
- apimodel注解的作用 (60)
- window.onerror (66)