我同意上面的答案,但我想我也会在测试方面加入一点:
在子系统之间存在交互的复杂系统中,依赖注入是我所知道的进行单元测试的最佳方式。
如果您有一个与逻辑单元 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)
进入这个逻辑:
// 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)
现在,为什么我们没有在许多动态语言中看到 IOC?
我想说的原因是我们在这些语言中没有看到太多的依赖注入。
...那是因为通常在它们中进行的测试是不存在的。
我听过各种各样的借口;与 DOM 交互使测试变得困难,我的代码很简单,不需要测试,动态语言不需要单元测试,因为它们很棒且富有表现力。
都是废话。
没有单元测试或代码覆盖率差的单元测试的项目没有任何借口。
...但是我看到的 javascript 和 python 项目的数量令人惊讶(特别选择这两个只是因为它们是一个感兴趣的领域,而且我看到的这种类型的项目比其他项目多)没有IoC,没有 DI,不出所料,没有测试。
这里的 guice 网站上有一篇关于 DI 的优秀文章:
http://code.google.com/p/google-guice/wiki/Motivation
动态语言无法解决任何这些问题。
总结:
- IoC 对事物有用,但主要用于实现 DI
- IoC 是 NOT xml 配置文件。 >_
- DI 对测试很有用
- 没有 IOC 表示没有 DI,这表明没有良好的测试。
- 使用 IoC。