我正在阅读有关依赖倒置和解耦的理论,但我看不出两者之间的区别。
依赖倒置谈论解耦功能组件,以便更高级别的组件不依赖于较低级别的组件。
解耦谈论同样的事情以及如何实现它。但是后来我们有了 IoC 容器,这让事情变得更糟了。为什么不将它们称为依赖反转容器甚至更好的依赖注入容器,因为它们服务于独立组件的运行时耦合?
然后我们有控制反转。它基本上和依赖倒置是一样的,不是吗?为什么用三个词来描述同一个东西?还是我瞎了?
三者有什么区别? IoC 在 IoC 容器中必须做什么?
解耦是一个非常普遍的原则,适用于许多领域。依赖倒置是一种特定的解耦形式,您可以通过将系统的较高级别与较低级别分离到库中并使用接口来将它们解耦。这使您可以更换系统的较低级别部件,而无需进行重大返工。
例如,不是系统的较高级别部分创建较低级别类的具体实例,而是可以使用 IoC 容器来解耦对象的创建方式。
控制反转是框架库使用的一种设计原则,它允许框架从应用程序中重新获得一些控制权。即,当某些用户界面事件发生时,窗口框架可以回调应用程序代码。 Martin Fowler 使用了“好莱坞原则”一词,如“不要打电话给我们,我们会打电话给你”。解耦是控制反转的重要组成部分。
但是,IoC 容器 与控制反转有什么关系呢? To quote Martin Fowler:
控制反转是一个过于笼统的术语,因此人们会感到困惑。因此,在与各种 IoC 倡导者进行了大量讨论后,我们确定了依赖注入这个名称。
(请注意,Martin Fowler 谈论的是依赖注入,而不是依赖倒置。)
IoC 容器有助于实现依赖注入,也许更好的术语是依赖注入容器。但是,IoC 容器名称似乎仍然存在。依赖注入是依赖倒置中的一个重要组成部分,但是使用 IoC 容器进行依赖注入可能会令人困惑,因为控制倒置是一个更广泛和更通用的原则。
您指出命名不是很一致,但这不应该是一个大惊喜,因为这些术语是独立发明和使用的,即使它们重叠。
依赖注入使用控制反转实现解耦。
我从 martinfowler.com 上的 DIP in the Wild 文章中找到以下解释,很容易理解(这里 DI = 依赖注入,DIP = 依赖反转原则,IoC = 控制反转):
DI 是关于一个对象如何获得依赖关系的。当外部提供依赖项时,系统正在使用 DI。 IoC 是关于谁发起呼叫。如果您的代码发起调用,它不是 IoC,如果容器/系统/库回调到您提供的代码,它是 IoC。另一方面,DIP 是关于从您的代码发送到它所调用的东西的消息的抽象级别。 (...) DI 是关于布线,IoC 是关于方向,而 DIP 是关于 [代码所依赖的对象的] 形状。
依赖倒置:依赖于抽象,而不是具体。
控制反转:主要与抽象,以及主要如何成为系统的粘合剂。
https://i.stack.imgur.com/OgaR1.png
这些是一些谈论这个的好帖子:
https://coderstower.com/2019/03/26/dependency-inversion-why-you-shouldnt-avoid-it/
https://coderstower.com/2019/04/02/main-and-abstraction-the-decoupled-peers/
https://coderstower.com/2019/04/09/inversion-of-control-putting-all-together/