我有全面的.NET背景,但最近一直在使用Python和Ruby。我发现自己在思考如何最好地为在 Ruby 中需要它们的对象提供依赖关系。
起初,我实际上并不认为DI和IoC框架需要与依赖项进行交互,因为动态语言(重新定义,mixins,stubs等)的宽容。然而,然后,我遇到了为什么动态语言不需要DI/IoC框架的答案。提供的理由不太适合我。我希望我能看到一个可以澄清事情的例子。
我有点不同意的推荐建议:
原因 1:可以在运行时更改依赖类(想想测试)
在为什么动态语言不需要IOC容器中,我们看到依赖类(非注入),例如X
,可以在测试中存根或模拟。当然,但这需要我们知道我们的System Under Test
取决于一种叫做X
的东西 .如果我们的System Under Test
突然依赖于N
而不是X
,我们现在必须记住嘲笑N
而不是X
。使用 DI 的好处是,我们永远不会意外地使用生产依赖项运行测试,因为我们总是会传入模拟依赖项。
原因 2:子类或使用构造函数注入进行测试
在每个人最喜欢的 goto 资源中,DI + Ruby、乐高、Play-Doh 和编程,我们看到了一个子类化待测系统以模拟依赖关系的示例。或者,我们可以使用构造函数注入。好的,所以B
取决于A
.我们调用B.get_dependency
它为B
提供了A
的实例。但是,如果A
取决于N
而X
呢?我们必须对链中的每个连续对象调用get_dependency
吗?
原因 3:依赖项可以混合或
修补Fabio提到我们可以只使用mixins/monkeypatch。所以X
混入N
.但问题是,如果X
取决于A
而B
呢?我们是否只是将mixin用于链中的每个依赖项?我看到它是如何工作的,但它可能会很快变得混乱和混乱。
旁注:许多用户说动态语言不需要DI框架。然而,Angular.JS确实受益于实现一个相当可靠的DI系统。Angular建立在JavaScript之上,JavaScript是一种动态语言。这种方法可以与Ruby或Python相媲美吗?
请记住,我并不是说我想强制DI/IoC进入Ruby,Python等。
虽然许多人认为不需要DI,但我同意你的看法,它确实需要很多;但有时它会与Python提供的其他技术混合在一起。我建议你看看金星,它可能有点冗长,但如果你来自.NET,你会看到这种关系。总之:Venusian允许您在不改变其行为的情况下注释您的方法。因此,你可以编写金星装饰器,这样你的单元测试就不会受到影响。例如,金字塔使用金星来注释视图。