Dependency injection 抽象不应该依赖于细节。细节应该取决于抽象?

Dependency injection 抽象不应该依赖于细节。细节应该取决于抽象?,dependency-injection,inversion-of-control,Dependency Injection,Inversion Of Control,在过去的几天里,我读了很多关于依赖注入/控制反转/依赖反转的文章。我认为,现在我对这个概念的理解好多了。但我仍然没有从维基百科上得到以下信息: A.不应使用高级模块 依赖于低级模块。二者都 应该依赖于抽象。 抽象不应依赖于细节。细节应该 依赖抽象 我理解高级模块的部分不应该 依赖于低级模块。但是,我对抽象和细节感到困惑。有人能帮我简化一下吗。谢谢。这意味着,如果细节发生变化,它们不应影响抽象。抽象是客户端查看对象的方式。物体内部到底发生了什么并不重要。让我们以一辆汽车为例,踏板、方向盘和变速杆都

在过去的几天里,我读了很多关于依赖注入/控制反转/依赖反转的文章。我认为,现在我对这个概念的理解好多了。但我仍然没有从维基百科上得到以下信息:

A.不应使用高级模块 依赖于低级模块。二者都 应该依赖于抽象。 抽象不应依赖于细节。细节应该 依赖抽象

我理解高级模块的部分不应该
依赖于低级模块。但是,我对抽象和细节感到困惑。有人能帮我简化一下吗。谢谢。

这意味着,如果细节发生变化,它们不应影响抽象。抽象是客户端查看对象的方式。物体内部到底发生了什么并不重要。让我们以一辆汽车为例,踏板、方向盘和变速杆都是发动机内部情况的抽象。不过,他们并不依赖细节,因为如果有人把我的旧发动机换成新发动机,我仍然可以在不知道发动机换了的情况下驾驶汽车


另一方面,细节必须符合抽象所说的内容。我不想安装一台突然导致刹车速度加倍的发动机。我可以以任何方式重新实现制动器,只要它们在外部的行为方式相同。

抽象和细节示例:流提供了读取令牌的接口。这是一个抽象概念


流的流实现必须实现抽象定义的接口:这就是它依赖于它的原因。如果它提供了一个不同的接口(一次读取100个字符),它就不能声称实现了相同的抽象。

想想你需要调用的工作,以及它离你当前编码的地方有多远。那里有一个光谱;您在it上的位置代表了调用该功能所需的工作量

抽象使这个位置更接近您正在编写的代码。例如,如果您必须调用web服务,您可以1)在需要使用它的地方直接编写调用代码,或者2)将这些细节放在抽象(例如接口)后面

在这种情况下,#1使您更接近频谱上的web服务,而#2使您更接近您的工作。抽象可以说是一种衡量你需要将思想延伸到多大程度才能理解你需要完成的工作的方法

这意味着每一项工作都可以被抽象,以便与使用它的代码“更接近”。通过让操作的双方都依赖于抽象,它们都变得更容易理解,并且任何一方都不必知道它们之间的差距——这就是抽象的工作


哇,这太抽象了。

抽象依赖于细节的一个有趣的例子是定义继承自的接口时。请看一下以下抽象:

公共接口ICCustomerRepository:IDisposable
{
客户GetById(Guid id);
客户[]GetAll();
}
注意
IDisposable
是一个特定于.NET的接口,但是您可以很容易地想象您的接口本身包含一个
Dispose
方法,而不是从这样的接口继承

icCustomerRepository
实现
IDisposable
可能看起来很方便。通过这种方式,任何调用方都可以处理存储库,通过这种方式,实现可以处理其内部使用的连接或工作单元


然而,现在编写接口时考虑到了某个实现,因为所有
icCustomerRepository
实现都需要清理任何资源这一点并不明显。因此,接口泄漏了实现细节,因此违反了依赖倒置原则。

我喜欢OP在理解这个概念时遇到困难-非常简洁明了的回答,谢谢。最好的解释