【发布时间】:2020-03-27 12:46:45
【问题描述】:
我已经阅读了很多关于依赖注入的文章以及观看了很多视频,但我仍然无法理解它。有没有人有一个很好的类比来解释它?
我看了敏捷之秋的第一部分截屏,还是有点迷茫。
【问题讨论】:
我已经阅读了很多关于依赖注入的文章以及观看了很多视频,但我仍然无法理解它。有没有人有一个很好的类比来解释它?
我看了敏捷之秋的第一部分截屏,还是有点迷茫。
【问题讨论】:
类比?我会试一试...如果没有带有音乐的 CD,您的 CD 播放器立体声将毫无用处...(取决于 CD)。如果他们用已经在里面的 CD 制作 CD 播放器,那会很快变得无聊......
因此他们构建了它们,以便您可以将 CD(它所依赖的)“注入”到播放器中。这样,您每次都可以注入不同的行为,并根据您注入的行为获得“不同”的行为(音乐)。
唯一的要求是 CD 必须与播放器定义的 界面兼容。 (您不能在 1992 年的 CD 播放器中播放蓝光光盘。)
【讨论】:
我能想到的最好的比喻是雇佣一名机械师。
没有依赖注入,你雇佣了一个技工,而技工带来了他自己的工具。他可能有糟糕的工具,他可能有很棒的工具,他可能在应该使用套筒的时候使用管子扳手。你不知道,也可能不在乎,只要他完成工作。
使用依赖注入,您聘请了一名技工,并为他提供了您希望他使用的工具。您可以选择您认为最适合您雇用他的工作的最佳或最合适的工具。
【讨论】:
将其视为“控制反转”模式的实现。我想,你的问题是,你太习惯了,你没有意识到它是如此简单。
让我们从头开始。
在早期,程序在代码中遵循给定的路径。调用函数的顺序由程序员给出。
在交互式程序中,例如大多数是任何程序,你不能说,在什么时候调用哪个函数。只需查看 GUI 或网站即可。你不能说,什么时候点击了什么按钮或链接。因此,对正在发生的事情的“控制”不再是在程序中,而是在外部来源。 “控制”已经倒转。该功能不再是“表演”,而是“聆听”。想想好莱坞的原则:“不要叫我们,我们叫你”。监听器是实现这种模式的一个很好的例子。
在当今“面向对象的世界”中,IoC 是通过函数或“方法”来实现的。
“依赖注入”现在的含义相同,但不是针对做某事的“方法”,而是针对保存数据的“对象”。
数据不再是持有它的对象的一部分。它在运行时被“注入”到对象中。留在好莱坞,想想电影明星,打高尔夫球来谈论生意,但为了保持身材,她会饿死自己,尽量减少肌肉重量,因此她一次只能携带一根球杆。
因此,在高尔夫球场上,她的比赛很大程度上取决于她所携带的一根球杆。
对她来说幸运的是,有球童,一次携带一大堆球杆,并且知道什么时候使用什么球杆。现在,她摆脱了携带高尔夫球杆的有限可能性。 “不要想着要穿什么具体的球杆,我们都知道,会在正确的时间为您提供正确的球杆”。
电影明星是客体,高尔夫球杆是客体的成员。这就是依赖注入。
【讨论】:
也许专注于“注入”部分?当我看到这个词时,我想到了注射器。将组件的依赖推送到组件的过程可以认为是注入到组件中。
就像身体一样,当它需要某种药物(它需要的成分)时,你可以将它注射到体内。
【讨论】:
在他们 2003 年的 JavaPolis 演示文稿 (slides) 中,Jon Tirsén 和 Aslak Hellesøy 有一个有趣的类比,即需要一个 Boy 来接吻的 Girl 对象。我似乎记得BoyFactory 有时被称为“夜总会”,但幻灯片中没有。
【讨论】:
另一个类比:假设您是一名开发人员,只要您愿意,就可以直接从市场上订购计算机科学书籍 - 您知道卖家及其价格。事实上,您的公司可能有首选卖家,您可以直接与他们联系。所有这一切都很好,但可能是一个新卖家现在提供了更好的价格,而您的公司想要改变“首选”卖家。
此时您必须进行以下更改 - 更新联系方式(和其他内容)以便使用新卖家。您仍然直接下订单。
现在考虑我们在两者之间引入一个新步骤,公司中有一个“图书馆”官员,你必须通过他才能拿到书。虽然存在新的依赖关系,但您现在不受卖方任何更改的影响:无论是卖方更改付款方式还是卖方本人已更改,您现在只需向图书管理员下订单,他就会为您取书。
【讨论】:
来自Head First Design Patterns:
记住,代码应该像晚上的莲花一样关闭(改变),而像早上的莲花一样打开(扩展)
可以通过注入其他类中定义的行为来配置启用 DI 的对象。为了创建许多变化,原始对象结构没有变化。注入可以通过让类在其构造函数中请求其他工作类来显式地进行,或者在 Python 等动态语言中使用猴子补丁时可能不太明显。
使用 Person 类的类比,您可以获取一个基本的人体框架,将一组器官传递给它,然后观察它的演变。 Person 并不直接知道器官是如何工作的,但他们的行为符合预期的界面并影响所有者的身心表现。
【讨论】:
魔术师的sleight of hand!你可能认为你看到的东西可能被秘密操纵或替换。
【讨论】:
生活中充满了依赖注入的类比:
【讨论】:
控制反转(依赖注入是其中的一种实现)的本质是将对象的使用与管理分离。
我使用的类比/示例是引擎。发动机需要燃料才能运行,即它依赖于燃料。但是,发动机不能为其所需的燃料负责。它只是“要求”燃料,并提供燃料(通常由汽车中的燃料泵提供)。
当你看得太深时,这个类比就开始崩溃了,因为发动机不需要燃料,它是由某种管理元素提供的,比如 ECU。或许可以将 ECU 与容器进行比较,但我不确定这是否有效。
【讨论】:
您的项目经理要求您编写一个应用程序。
你可以根据你目前的职业经验编写一些代码,但这不太可能是你的 PM 想要的。
如果您的 PM 依赖项为 您 注入了应用程序的规范,那就更好了。现在您的代码将与他给您的规范相关。
如果您被告知源存储库在哪里会更好。
如果您被告知技术平台是什么,那就更好了。
如果你被告知什么时候需要这样做会更好。
等等。
【讨论】:
我认为一个很好的类比是一个 6 岁的孩子有一套乐高积木。
您希望您的对象像乐高积木一样。每一个都独立于所有其他的,但提供了一个清晰的界面来将它们连接到其他的。将它们连接在一起时,只要它们具有匹配的接口,您将哪两块砖连接在一起并不重要。
你的依赖注入框架就像六岁的孩子。他按照说明(即您的配置文件、注释等)以特定方式将特定积木连接在一起以制作特定模型。
当然,由于积木的界面非常通用,它们可以以多种不同的方式组合在一起,因此很容易想出新的指令集,让 6 岁的孩子可以用来制作完全不同的用同样的积木建模。
【讨论】: