为什么动态语言不需要IOC容器

mik*_*may 42 dynamic-languages ioc-container

第68号羊群编号播客中的某人,http://herdingcode.com/herding-code-68-new-year-shenanigans/,声称IOC容器没有Python或Javascript的地方,或者说是这样的话.我认为这是传统智慧,它适用于所有动态语言.为什么?动态语言是什么让IOC容器变得不必要?

Nig*_*rne 46

IoC提供了一种机制来打破对象在另一个类上调用"new"时所获得的耦合.这种耦合将调用对象与它实现的任何接口的实例化实现联系起来.

在静态语言中,当您按名称引用类(调用new它)时,没有歧义.这是与特定类的紧密耦合.

在动态语言中,调用new X是一个占位符,用于"实例化X在执行点定义的任何类".这是一个更松散的耦合,因为它只与名称相关联X.

这种微妙的差异意味着在动态语言中你通常可以改变它是什么X,所以关于实例化哪个类的决定仍然可以在调用类之外修改.

但是,我个人发现IoC有两个优点,我依靠动态语言来实现注入.

通过构造函数传递依赖关系的一个副作用是,最终得到的"构建块"类非常分离,可重用且易于测试.他们不知道他们打算使用哪种上下文,因此您可以在所有地方重复使用它们.

另一个结果是有明确的代码来进行布线.正确完成这完全代表了应用程序的结构,它分解为子系统和生命周期.这使得人们明确地决定他们想要将他们的类关联到哪个生命周期或子系统(在编写布线代码时),并在编写类时专注于对象的行为.

就像JörgWMittag所说的那样...... "这些工具是不必要的,设计原则不是." 我认为它们是不必要的,但是做得对,仍然很有价值.

  • 问题不是关于IoC**容器**而不是IoC的概念吗? (3认同)

Ste*_*ntz 25

我有不同的意见.我认为IOC容器肯定在动态语言中起作用.

我不同意这样的观点,即一种动态的语言不需要一个结构清晰的对象组合.或者动态语言"提供"相同的功能.

IOC容器只是管理此组织的工具.

即使是动态语言,我也希望将组件"连接"起来.没有在这些组件之间建立硬依赖关系.或者甚至可能没有为这些组件指定实际的实现类.


Dou*_*oug 20

我同意上面的答案,但我认为我在这里也有一些关于测试的问题:

在子系统之间存在交互的复杂系统中,依赖注入是我知道进行单元测试的最佳方式.

如果你有一个与逻辑单元Y已知交互的逻辑单元X,你可以创建一个具有预定义行为的MockY并显式测试X的逻辑.

没有依赖注入,编写测试是一场噩梦.你无法获得良好的代码覆盖率.一些框架(例如django)通过启动模拟数据库实例来进行测试等等来解决这个问题,但这对问题来说基本上是一个糟糕的解决方案.

应该有两种测试:

  • 在任何环境中运行的单元测试,并测试各个代码单元的逻辑.
  • 用于测试组合应用程序逻辑的集成/功能测试.

现在回答这个问题:IoC.IoC有什么用?这对于一些事情来说很方便,但它真的很适合使用依赖注入更容易:

// Do this every time you want an instance of myServiceType
var SystemA = new SystemA()
var SystemB = new SystemB()
var SystemC = new SystemC(SystemA, "OtherThing")
var SystemD = new SystemD(SystemB, SystemC)
var IRepo = new MySqlRepo()
var myService = new myServiceType(SystemD, IRepo)
Run Code Online (Sandbox Code Playgroud)

进入这个逻辑:

// Do this at application start
Container.Register(ISystemA, SystemA)
Container.Register(ISystemB, SystemB)
Container.Register(ISystemC, SystemC)
Container.Register(ISystemD, SystemD)
Container.Register(IRepo, MySqlRepo)
Container.Register(myServiceType)

// Do this any time you like
var myService = Container.resolve(myServiceType)
Run Code Online (Sandbox Code Playgroud)

现在,为什么我们不在许多动态语言中看到IOC?

我要说的原因是我们在这些语言中看不到很多依赖注入.

......那将是因为通常在其中进行的测试不存在.

我听说过各种各样的借口; 与DOM交互使测试变得困难,我的代码很简单,不需要测试,动态语言不需要单元测试,因为它们非常棒且富有表现力.

这都是胡说八道.

没有任何借口为一个项目没有单元测试和单元测试的代码覆盖率差.

...但是我看到的javascript和python项目的数量令人惊讶(仅仅因为它们是一个感兴趣的领域并且我看到了比其他项目更多的这类项目而选择这两个项目)没有IoC,没有DI,并且不出所料,没有测试.

guice网站上有关于DI的优秀文章:http: //code.google.com/p/google-guice/wiki/Motivation

动态语言没有解决任何这些问题.

摘要:

  • IoC对于事物很有用,但主要用于实现DI
  • IoC 不是 xml配置文件.> _ <
  • DI对测试很有用
  • 缺乏IOC表明没有DI,这表明没有良好的测试.
  • 使用IoC.


Jör*_*tag 17

因为它们已经内置于语言中.

IoC容器提供两件事:

  • 动态绑定
  • 动态语言(通常是一个非常糟糕的语言,构建在XML之上或基于Java注释/ .NET属性的新版本)

动态绑定已经是动态语言的一部分,动态语言已经是动态语言.因此,IoC容器根本没有意义:该语言已经是IoC容器.

另一种看待它的方法:IoC容器允许你做什么?它允许您将独立组件连接在一起并将它们连接到一个应用程序中,而不需要任何组件相互了解.在应用程序中有一个连接独立部分的名称:脚本!(这几乎就是脚本的定义.)许多动态语言碰巧也非常擅长编写脚本,因此它们非常适合作为IoC容器.

请注意,我不是在谈论依赖注入或控制反转.DI和IOC都只是在动态语言一样重要,因为它们是在静态语言,对于完全相同的原因.我所说的是IoC容器和DI框架.这些工具是不必要的,设计原则不是.

  • 对于像Java这样的语言,你的观点是否同样有效?您可以像使用任何其他语言一样简单地在Java中连接Java对象. (2认同)