在动态语言中是否需要依赖注入?

时间:2009-12-24 00:43:12

标签: dependency-injection dynamic-languages

为了编写可测试的C#代码,我大量使用DI。

但是最近我一直在搞乱IronPython并且发现你可以模拟任何方法/类/函数等...你喜欢,对DI的需求已经消失了。

这适用于像Python这样的动态联盟吗?

而不是:

class Person(Address) {
...

你可以:

class Person() {
...
    // Address initialised in here.

对于动态语言而言,因此根本不需要使用manaual DI进行动态联盟。

对此有何建议?

4 个答案:

答案 0 :(得分:10)

依赖注入也是关于如何将事物连接在一起的 - 这与依赖对象的可模拟性无关。拥有Foo - 需要Bar的实例 - 某些类型的实例直接实例化它并让它完全忽略获取的方式之间存在差异>只要 它就连接。

如果使用依赖注入,可以获得更好的可测试性。但反过来却不是这样。通过能够覆盖任何东西来简化可测试性并不会带来依赖注入的其他优点。由于这些原因,Python有很多组件/ DI框架可供使用。

答案 1 :(得分:10)

我非常不同意您在动态类型语言中不需要依赖注入的说法。 DI有用和必要的原因完全独立于语言的输入规则。

主要区别在于动态类型语言中的DI简单易行:您不需要重量级框架和大量XML配置。

例如,在Ruby中,只有两个DI框架。两者都是由Java程序员编写的。这两个框架都没有被单个项目使用。甚至不是那些框架的作者

然而,DI在Ruby中被广泛使用。

作为这两个框架的作者,Jamis Buck在RubyConf 2008上发表了一篇名为 Recovering from Enterprise 的演讲,讲述了他编写这些框架的方式和原因,以及为什么这是一个坏主意,这非常值得一看。如果您想阅读,还有一个accompanying blog post。 (每当他说“Ruby”时,只需用“Python”代替,而且一切都同样有效。)

答案 2 :(得分:0)

我会再试一次。我的最后一个答案错过了一英里的问题并缩小了主题。

使用伪代码,依赖注入表示:

class Person
  def Chat() { 
    someOperation("X","Y","Z")
  end
end
...
Person.new().Chat()

并在:

class Person
  initialize(a,b,c)
    @a=a
    @b=b
    @c=c
  end
  def Chat()
    someOperation(@a,@b,@c)
  end
end
...
Person.new("X","Y","Z").Chat()

,.,并且通常将对象和调用放入不同的文件中以用于SCM目的。

“X”,“Y”或“Z”是否可以模仿(......如果它们是对象......(!)......(!)......)与是否完全无关DI很好。真。 : - )

DI在Python或Ruby中更容易,就像许多其他任务一样,因为有更多的脚本方法,如Jörg所说;当然还有一种文化和倾向,即常量和适配器将被填充到模型和全局常量中。

对我来说实际上,DI是将这些应用程序参数,API常量和工厂分离到单独文件中的第一步,以帮助使您的修订跟踪报告看起来不像意大利面(“AppController上的那些额外的签名要更改配置..?或更新代码......?“)和更多通知,更容易阅读。

我的建议:继续使用DI ......: - )

答案 3 :(得分:-2)

我认为您提出的问题似乎与最佳做法有关,但实际上是关于运行时性能。

摆脱依赖注入?软件发布经理如何在晚上睡觉?

要执行的功能测试肯定会使程序减慢一两个小时。

// my generic function entry point - IronPython
if func="a":
  ...
if func="b":
  ...
if func="c":
  ...

您可以将标准Python与类一起使用...或者您可以为函数指针成员分配函数指针。它是什么样的野兽......?我知道我知道。 Python我认为很难定义,但我喜欢它。而且我非常喜欢和高度重视依赖注入,而不是我已经很久没想到要为这种做法分配如此冗长的名字了。