我在 .NET 方面有全面的背景,但最近一直在使用 Python 和 Ruby。我发现自己在思考如何最好地为 Ruby 中需要它们的对象提供依赖关系。
起初,我实际上并不认为 DI 和 IoC 框架需要与依赖项进行交互,因为动态语言(例如重新定义、mixins、存根等)的宽松性。然而,然后,我遇到了为什么动态语言不需要DI/IoC 框架的答案。提供的理由对我来说不太合适。我希望我能看到一个可以解决问题的例子。
我有点不同意的推荐建议:
原因 1:可以在运行时更改依赖类(想想测试)
在为什么动态语言不需要 IOC 容器中,我们看到依赖类(非注入)X
可以在测试中被存根或模拟。当然,但这需要我们知道我们System Under Test
依赖于一个叫做X
. 如果我们System Under Test
突然依赖于N
而不是X
,我们现在必须记住要模拟N
而不是X
。使用 DI 的好处是我们永远不会意外地使用生产依赖项运行测试,因为我们总是会传入模拟依赖项。
原因二:子类化或者使用构造函数注入进行测试
在每个人最喜欢的关于 DI + Ruby、 LEGO、Play-Doh 和 Programming的所有东西的 goto 资源中,我们看到了一个将被测系统子类化以模拟依赖关系的示例。或者,我们可以使用构造函数注入。好的,所以B
取决于A
. 我们调用B.get_dependency
which 提供B
了一个A
. 但是如果A
取决于N
哪个取决于X
呢?我们必须调用get_dependency
链中的每个连续对象吗?
原因3:依赖可以混入或者monkeypatched
Fabio 提到我们可以只使用 mixins/monkeypatch。所以X
混入到N
. 但问题是如果X
取决于A
哪个取决于B
?我们是否只对链下的每个依赖项使用 mixins?我知道它是如何工作的,但它很快就会变得混乱和混乱。
旁注:许多用户说动态语言不需要 DI 框架。然而,Angular.JS 确实受益于实现了一个非常可靠的 DI 系统。Angular 是基于 JavaScript 构建的,这是一种动态语言。这种方法可以与 Ruby 或 Python 相媲美吗?
请记住,我并不是说我想将DI/IoC强制转换为 Ruby、Python 等。