1

我目前正在阅读有关依赖倒置原则的其他优秀教程

https://www.baeldung.com/java-dependency-inversion-principle

尽管思考了相当长的时间,但有些东西我无法解释

DIP 定义的相关部分:“高级模块不应该依赖于低级模块。两者都应该依赖于抽象。”

在第 3.1 点“设计选择和 DIP”中,作者通过一个示例介绍了原理,其中一个StringProcessor类使用 aStringReader和一个StringWriter组件,并使用接口/类和包提供多种设计选择。我的问题是选择 2

StringReader并且StringWriter是与实现一起放置在同一包中的接口。StringProcessor现在依赖于抽象,但低级组件不依赖。我们还没有实现依赖关系的反转”

StringProcessor是依赖于“抽象”即接口的“高级组件”,从而从一侧实现DIP定义,这一点很清楚。现在给出在第一句中提到的文章“实现”中使用的术语,例如 a和一个类将是这里的“低级组件”,而我只是无法理解它们如何不依赖于“抽象” "即在他们实现的接口上,不管包含的包StringReaderStringWriterConcreteStringReaderConcreteStringWriter

显然,从代码组织的角度来看,将实现与其接口放在同一个包中可能不是最好的,但是这如何违反上面的逐字 DIP 定义取决于抽象目前超出我的理解

也许对该主题有更深入理论知识的人可以在这里帮助我

4

2 回答 2

2

隐含的一般概念是一个包等同于一个抽象级别。因此,在第 3.1.2 节中,具体实现“拥有”它们的抽象,因为它们位于同一个包中;因为在任何发布包的地方,这些实现都是顺其自然的。共享包的类之间的耦合在一定程度上体现在语法上,即使在 Java 8 中也是如此。例如,import语句不是必需的,具有默认访问修饰符的类和方法是可见的。

尽管如此,根据 JPMS 的特性,更容易看出第 3.1.2 节中的缺陷。模块是在包级别定义的,将包是单个抽象级别的概念形式化。就 DIP 而言,依赖关系也在包级别考虑。如果一个包包含具体的实现,它被认为是低级的,并且不应该有传入的依赖项。

深入探讨该主题的整本书是Java Application Architecture: Modularity Patterns

于 2021-01-03T01:16:52.260 回答
1

“StringReader 和 StringWriter 是与实现一起放在同一个包中的接口。StringProcessor 现在依赖于抽象,但低级组件不依赖。我们还没有实现依赖倒置”

虽然它确实不是 DIP,但 IMO 的解释是错误的。问题是作者未能识别类/组件和层/包/模块之间的区别。DIP是只适用于模块之间关系的原理,显然不适用于单个模块的情况。

至于第四点,

同样,第 4 项是一个更加解耦的 DIP 实现。在该模式的变体中,高级组件和低级组件都没有抽象的所有权。

我们在这里需要非常小心,因为“所有权”超越了“在同一个包中”。

例如,这将违反 DIP

在此处输入图像描述

于 2021-01-04T02:11:18.183 回答