依赖倒置设计选择题

问题描述

我目前正在阅读一本关于依赖倒置原则的优秀教程

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

虽然我想了很长时间,但我还是无法解释一些事情

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

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

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

StringProcessor“高级组件”,它依赖于 “抽象”StringReaderStringWriter 接口,从而从一方面实现 DIP 定义,这很清楚。现在给出在第一句中提到的文章“实现”中使用的术语,例如ConcreteStringReaderConcreteStringWriter 类将是 “低级组件”,我只是无法理解它们如何不依赖于 ”抽象” 即在它们实现的接口上,无论包含哪些包

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

也许对这个主题有更深入理论知识的人可能会帮助我

解决方法

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

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

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

,

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

虽然它确实不是 DIP,但 IMO 的解释是错误的。问题是作者没能分辨出类/组件和层/包/模块之间的区别。 DIP 是一个只适用于模块间关系的原则,对于单个模块显然不适用。

至于第 4 点,

同样,第 4 项是一个更加解耦的 DIP 实现。在这 模式的变体,既不是高级组件也不是 低级的拥有抽象的所有权。

我们在这里需要非常小心,因为“所有权”不仅仅是“在同一个包裹中”。

例如这将是 DIP 违规

enter image description here

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...