“控制反转”、“依赖反转”和“解耦”的区别

我正在阅读关于 依赖关系反转脱钩的理论,我看不出它们之间的区别。

依赖性反转 讨论解耦功能组件,这样高级组件就不依赖于低级组件。

解耦 谈论的是同样的事情以及如何实现它。但是 IoC 集装箱会把事情搞得更糟。为什么它们不被称为 依赖性反转容器或者更好的 依赖注入容器,因为它们提供独立组件的运行时耦合?

然后是 控制反转。基本上和 依赖性反转是一样的,不是吗?为什么有三个术语描述同一件事?还是我瞎了?

  1. 这三者之间有什么区别?
  2. 在 IoC 容器中,IoC 必须做什么?
25859 次浏览

Dependency Injection achieves Decoupling using Inversion of Control.

Decoupling is a very general principle applicable in many fields. Dependency inversion is a specific form of decoupling where you decouple the higher levels of your system from the lower levels by separating them into libraries and using interfaces. This allows you to replace lower level parts of your system without major rework.

For example, instead of the higher level parts of the system creating concrete instances of the lower level classes, an IoC container can be used to decouple how objects are created.

Inversion of control is a design principle used by framework libraries that allow the framework to regain some control from the application. I.e., a windowing framework may call back into application code when certain user interface events occur. Martin Fowler uses the term Hollywood Principle as in Don't call us, we'll call you. Decoupling is an important part of inversion of control.

But what has an IoC container to do with inversion of control? To quote Martin Fowler:

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.

(Note that Martin Fowler talks about dependency injection, not dependency inversion.)

An IoC container helps to implement dependency injection and perhaps a better term would be dependency injection container. However, the IoC container name seems to stick. Dependency injection is an important component in dependency inversion, but the use of IoC containers for dependency injection can be confusing as inversion of control is a broader and more generic principle.

You point out that the naming isn't very consistent but that shouldn't be a big surprise as these terms have been independently invented and used even though they overlap.

I find the following explanation from DIP in the Wild article on martinfowler.com straightforward to understand (here DI = Dependency Injection, DIP = Dependency Inversion Principle, IoC = Inversion of Control):

DI is about how one object acquires a dependency. When a dependency is provided externally, then the system is using DI. IoC is about who initiates the call. If your code initiates a call, it is not IoC, if the container/system/library calls back into code that you provided it, is it IoC.

DIP, on the other hand, is about the level of the abstraction in the messages sent from your code to the thing it is calling. (...) DI is about wiring, IoC is about direction, and DIP is about shape [of the object upon which the code depends].

Dependency inversion: Depend on abstractions, not on concretions.

Inversion of control: Main vs Abstraction, and how the Main is the glue of the systems.

DIP and IoC

These are some good posts talking about this:

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/