25

我已经阅读了很多关于依赖注入的文章以及观看了很多视频,但我仍然无法理解它。有没有人有一个很好的类比来解释它?

我看了敏捷之秋截屏的第一部分,仍然有点困惑。

4

12 回答 12

65

类比?我会试一试...如果没有带有音乐的 CD,您的 CD 播放器立体声将毫无用处...(这取决于 CD)。如果他们用已经在里面的 CD 制作 CD 播放器,那会很快变得无聊……

因此他们构建了它们,以便您可以将 CD(它所依赖的)“注入”到播放器中。这样,您每次都可以注入不同的行为,并根据您注入的行为获得“不同”的行为(音乐)。

唯一的要求是 CD 必须与播放器定义的接口兼容。(您不能在 1992 年的 CD 播放器中播放蓝光光盘。)

于 2009-01-08T14:43:18.923 回答
7

我能想到的最好的比喻是雇佣一名机械师。

在没有依赖注入的情况下,你雇佣了一名技工,而技工带来了他自己的工具。他可能有糟糕的工具,他可能有很棒的工具,当他应该使用套筒时,他可能正在使用管子扳手。你不知道,也可能不在乎,只要他完成工作。

通过依赖注入,你雇佣了一名技工,你为他提供了你希望他使用的工具。您可以选择您认为最适合或最适合您雇用他的工作的工具。

于 2009-01-08T14:45:48.607 回答
2

将其视为“控制反转”模式的实现。我想,你的问题是,你太习惯了,你没有意识到它这么简单。

让我们从头开始。

在早期,程序在代码中遵循给定的路径。调用函数的顺序由程序员给出。

在交互式程序中,例如大多数是 ANY 程序,你不能说什么时候调用哪个函数。只需查看 GUI 或网站即可。你不能说,什么时候点击了什么按钮或链接。因此,对正在发生的事情的“控制”不再是在程序中,而是在外部来源。“控制”已经倒转。该功能不再是“表演”,而是“聆听”。想想好莱坞的原则:“不要叫我们,我们叫你”。监听器是实现这种模式的一个很好的例子。

在当今“面向对象的世界”中,IoC 是通过函数或“方法”来实现的。

“依赖注入”现在的意思是一样的,但不是针对做某事的“方法” ,而是针对保存数据的“对象” 。

数据不再是持有它的对象的一部分。它在运行时被“注入”到对象中。留在好莱坞,想想一个电影明星,打高尔夫球来谈论生意,但为了保持身材,她渴望自己,尽量减少她的肌肉重量,因此她一次只能携带一个球杆。

因此,在高尔夫球场上,她的比赛很大程度上取决于她所携带的一根球杆。

对她来说幸运的是,有球童,一次携带一大堆球杆,并且知道什么时候使用什么球杆。现在,她摆脱了携带高尔夫球杆的有限可能性。“不要想着要穿一个具体的俱乐部,我们都知道,并在正确的时间为您提供正确的俱乐部”。

电影明星是客体,高尔夫球杆是客体的成员。这就是依赖注入。

于 2009-01-08T15:19:31.410 回答
1

也许专注于“注入”部分?当我看到这个词时,我想到了注射器。将组件的依赖推送到组件的过程可以认为是注入到组件中。

就像身体一样,当它需要某种药物(它需要的成分)时,您可以将其注入体内。

于 2009-01-08T14:45:37.313 回答
1

在 2003 年的 JavaPolis 演示文稿(幻灯片)中,Jon Tirsén 和 Aslak Hellesøy 用一个需要亲吻的Girl物体进行了有趣的类比。Boy我似乎记得BoyFactory有时被称为“夜总会”,但幻灯片中没有。

于 2009-01-08T14:54:53.003 回答
1

另一个类比:假设您是一名开发人员,只要您愿意,您就可以直接从市场上订购计算机科学书籍——您知道卖家和他们的价格。事实上,您的公司可能有首选卖家,您可以直接与他们联系。所有这一切都很好,但可能是一个新卖家现在提供了更好的价格,而您的公司想要改变“首选”卖家。

此时您必须进行以下更改 - 更新联系方式(和其他内容)以使用新卖家。您仍然直接下订单。

现在考虑我们在两者之间引入一个新步骤,公司中有一个“图书馆”官员,你必须通过他才能拿到书。虽然存在新的依赖关系,但您现在不受卖方任何更改的影响:无论是卖方更改付款方式还是卖方本人已更改,您现在只需向图书管理员下订单,他就会为您取书。

于 2009-01-08T14:58:36.163 回答
1

Head First 设计模式

请记住,代码应该像晚上的莲花一样关闭(改变),而像早上的莲花一样开放(扩展)

可以通过注入其他类中定义的行为来配置启用 DI 的对象。原始对象结构没有更改以创建许多变化。注入可以通过在其构造函数中让类请求其他工作类来显式地进行,或者在 Python 等动态语言中使用猴子补丁时可能不太明显。

使用 Person 类的类比,您可以采用一个基本的人体框架,将一组器官传递给它,然后观察它的演变。Person 并不直接知道器官是如何工作的,但它们的行为符合预期的界面并影响所有者的身心表现。

于 2009-01-08T17:06:06.513 回答
1

魔术师的绝招!你可能认为你看到的东西可能会被秘密操纵或替换。

于 2009-01-08T17:14:57.527 回答
1

生活中充满了依赖注入的类比:

  • 打印机墨盒
  • 数码设备 - 电池
  • 信-邮票
  • 音乐家 - 乐器
  • 公车司机
  • 病痛丸
于 2009-01-08T17:30:06.233 回答
1

控制反转(依赖注入是其中的一种实现)的本质是将对象的使用与对象的管理分离。

我使用的类比/示例是引擎。发动机需要燃料才能运行,即它依赖于燃料。但是,发动机不能为其所需的燃料负责。它只是“要求”燃料,并提供燃料(通常由汽车中的燃料泵提供)。

当你看得太深时,这个类比就会开始崩溃,因为发动机不需要燃料,它是由某种管理元素提供的,比如 ECU。也许可以将 ECU 与容器进行比较,但我不确定这是否有效。

于 2010-10-15T08:52:24.767 回答
0

您的项目经理要求您编写一个应用程序。

你可以根据你目前的职业经验编写一些代码,但这不太可能是你的 PM 想要的。

如果您的 PM 依赖项为您注入了应用程序的规范,那就更好了。现在您的代码将与他给您的规范相关。

如果您被告知源存储库在哪里,那就更好了。

如果您被告知技术平台是什么,那就更好了。

如果您被告知何时需要这样做,那就更好了。

ETC..

于 2009-01-08T14:47:09.617 回答
0

我认为一个很好的类比是一个六岁的孩子带着一套乐高积木。

您希望您的对象像乐高积木一样。每一个都独立于所有其他的,但提供了一个清晰的界面来将它们连接到其他的。将它们连接在一起时,只要它们具有匹配的接口,您将哪两块砖连接在一起并不重要。

你的依赖注入框架就像六岁的孩子。他按照说明(即您的配置文件、注释等)以特定方式将特定积木连接在一起以制作特定模型。

当然,由于积木的界面非常通用,它们可以以许多不同的方式组合在一起,所以很容易想出新的指令集,六岁的孩子可以用它们来制作一个完全不同的模型同样的砖。

于 2011-12-30T04:08:07.157 回答