我在 .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_dependencywhich 提供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 等。