问题标签 [dependency-inversion]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
578 浏览

c++ - SOLID:DIP 是否意味着禁止对对象的组合/聚合?

我正在尝试理解和应用 SOLID 原则。关于依赖倒置原则,是否意味着禁止组合/聚合到对象?所以必须总是使用接口来访问另一个类方法?

我的意思是:

必须改为:

我认为(或者至少我希望)我理解了这个原则。但想知道它是否可以这样改写。事实上,我读到的关于 DIP 的东西建议使用接口。

谢谢!

0 投票
1 回答
683 浏览

unit-testing - 依赖倒置、猴子补丁是否都最适合单元测试?

这些都是人为的例子,主要是 JavaScript,但这个问题是与语言无关的,并且通常集中在单元测试上。

代码库

单元测试(猴子补丁样式)

问题

  • 测试与实现紧密耦合。
  • 在某些语言中可能无法进行猴子修补。
  • 未经测试的副作用依赖项更改不会破坏现有测试(即静默和未修补的依赖项)。

单元测试(依赖倒置/注入风格)

我了解依赖反转/注入、存根、伪造、模拟等的概念,但尚未在现实​​世界的多级函数调用中遇到它。即到目前为止,我所看到的示例仅显示了调用者和被调用者。

这就是我将其推断为两个以上的级别:

问题

  • 测试与实现紧密耦合。
  • 顶级函数因未使用的参数而臃肿(只是传递下来)。
  • 您如何测试最高级别的函数(在这种情况下为 func1)?每次反转依赖关系时,都会无意中创建另一个级别。

问题

在现实世界中进行单元测试(即深层函数调用)时,处理存根依赖关系的最佳方法或策略是什么?

0 投票
3 回答
660 浏览

java - 依赖倒置原则

我一直在阅读可靠的 OOP 原则(依赖倒置原则),但并不太了解它是如何工作的。

当一个类明确知道另一个类的设计和实现时,对一个类的更改会增加破坏另一个类的风险。

假设我有一个取决于课程的学生,如果我会改变课程对学生的影响。使用 DI 是一样的吗?我的意思是 DI 替换新运算符,那又如何呢?学生仍然取决于课程
,请您举一些例子。
谢谢

更新 1

(场景)如果我假设该类只有默认构造函数并且它永远不会使用任何实例变量来实例化new Course(name, .......)

更新 2

例子

现在发生的事情是我们的复制模块需要了解打印机和磁盘,您可以想象在这些情况下那些神奇的 if-else 语句来拯救我们。随着新需求的出现,您可能会向此复制模块添加越来越多的依赖项。归根结底,您最终会得到一个非常复杂、难以维护和难以理解的设计。

你能在这个例子中展示具体的依赖倒置消除了使用神奇的 if-else 语句的简单例子吗?

0 投票
2 回答
1005 浏览

c++ - 澄清依赖倒置原则

对不起,我在软件工程上交叉发帖,不知道它被不赞成。

对于那些好奇的人,我得到的答案正是我想要的:https ://softwareengineering.stackexchange.com/a/347143/269571


原始问题

我正在阅读Robert C. Martin《敏捷软件开发、原则、模式和实践》一书。

当他谈到依赖倒置原则时,他给出了以下 DIP 违规示例:

DIP 违规

这对我来说似乎很清楚,因为高级对象Button依赖于低级对象Lamp

他带来的解决方案是:

解决方案

他创建了一个接口,这样Button就不再依赖于对象了Lamp

这个理论对我来说似乎很清楚,但是我无法在现实生活中的项目中使用这个原理。

  • 谁来SwitchableDevice确定需要调用哪些类(实现)?

  • 告诉Button他需要打开/关闭哪些设备?

  • 你如何告诉一个使用抽象事物的对象它需要使用哪些具体事物?(如果这个问题完全错误,请纠正我)

如果我的问题有任何不清楚的地方,请告诉我,我很乐意为您澄清。

0 投票
1 回答
1307 浏览

c# - 依赖倒置原则:高级和低级模块示例

我正在通过以下链接了解在依赖倒置原则的上下文中高级和低级模块的含义。

根据那里给出的解释,下面的代码片段是一个好的/合适的例子吗?

0 投票
2 回答
721 浏览

dependency-injection - 具体类注入被认为是不好的做法

我很好奇依赖倒置原则,以及是否应该一直严格执行。

我知道使用注入接口通常会促进松散耦合,这会产生积极影响。

但是,某些类型的类很可能总是只有一个实现,并且可能不会随着时间而改变。我真的在质疑让每个对象都由一个接口支持,例如 FooService,与 FooServiceImpl。

我处于两难境地,因为我认为具体的类注入通常被许多人所反对。

tl;dr
是否应该始终只使用接口进行依赖注入,即使某些类不太可能更改,因此,通过接口支持它似乎会增加不必要的复杂性?

0 投票
1 回答
118 浏览

oop - 依赖倒置真的有效吗?

我已经阅读了有关 Dependency Inversion(SOLID 中的“D”)的内容,并在此处查看了一些示例。

但是,我看不到如何完全摆脱依赖!

根据文章,通过在消费者包中引入合同/接口,可以将关系 Consumer --> Utility 更改为 Utility --> Consumer。

此外,可以通过将合约/接口移动到单独的包(例如 Consumer --> Contracts <-- Utility)来完全解耦反向依赖关系。

现在,有了上面的布局;消费者使用实用程序不应该有工厂吗?然后带回原始依赖项,如下所示:

消费者 --> 工厂 --> 实用程序

0 投票
1 回答
434 浏览

java - 抽象应该与高级模块一起打包?

维基说

在依赖倒置的直接应用中,抽象由上层/策略层拥有。该架构将较高/策略组件和定义较低服务的抽象组合在同一个包中。较低级别的层是通过这些抽象类或接口的继承/实现来创建的。

理想情况下,正如维基文章所说(在实现部分下的方法 2 中)抽象模块应该是松散耦合的单独模块,

但是我对引用声明的方法1有疑问。根据我的经验,无论 2 没有实现/可能,我总是看到抽象类是用低级模块而不是高级模块打包的。

用高级包封装抽象/接口的缺点是,如果有 10 个高级模块调用给定的低级模块,那么我们需要将接口打包在所有 10 个模块中。考虑到我必须在界面中添加一个方法,我必须修改所有 10 个模块才能添加该方法。不是吗?因此,根据我的理解,抽象类应该与低级模块而不是高级模块一起打包。

纠正我如果我在这里错了吗?

0 投票
1 回答
1464 浏览

visual-studio - 结构图依赖注入问题:未注册默认实例且无法自动确定

我刚刚从 nuget 添加了结构映射,并像这样修改了 DefaultRegistry 文件

公共类 DefaultRegistry : Registry { #region 构造函数和析构函数

控制器代码是

我得到 StructureMap.StructureMapConfigurationException 的异常:'没有注册默认实例,无法自动确定类型'Application.TaskStatus.IGetTaskStatusList'

0 投票
1 回答
62 浏览

dependency-injection - 动态配置根?基于数据库调用?

我有一个应用程序,它在启动时知道足以选择数据库并提取配置对象。

然后它在那个配置对象上执行,处理一堆东西,拉另一个配置对象,在那个配置对象上执行,等等,在一个循环中。

现在,我在应用程序的开头有一个配置根,可以配置它可以配置的所有内容。但是由于它在 db 调用之后才知道所有内容,因此该点之后的所有对象分支都隐藏在工厂工厂的后面,因此它们可以处理配置对象中发生的任何配置。

我的问题是,这正常吗?似乎另一种选择是拥有两个配置根或两个 DI 容器。一个在 db 调用之前,一个在 db 调用之后。

如果我可以在 db 调用之后执行我的 DI root,我就可以将东西直接连接到那里的容器中,从而从我的代码中删除大量工厂,这些工厂只存在,因为在应用程序启动时,我不是确定需要什么。但这似乎很奇怪。这也意味着我必须在每次迭代时重新创建我的容器或第二个容器,这看起来很奇怪。

编辑:我刚刚发现 StructureMap 对于几乎这个确切的用例有一个嵌套容器功能,所以我肯定在这里:http ://structuremap.github.io/the-container/nested-containers/

编辑:我没有得到任何回复,但无论如何后来都能回答这个问题。在下面添加了我的答案。