是(几乎)每个类注入DI容器的反模式?

时间:2012-04-27 19:11:11

标签: dependency-injection

最近我发现自己并没有过多地为类定义依赖关系并在构造函数中传递它们,但我总是传递DI容器并将其保存在私有属性中。这样我的类就没有非常明确的依赖关系,我在需要时从容器中获取所有内容。

不过我对这个解决方案有不好的感觉(除了访问容器引起的开销),但我真的不能想到太多的缺点。也许松散的依赖关系定义会降低类的可移植性,或者在重构时会出现意外......?

您如何看待这个?

2 个答案:

答案 0 :(得分:11)

绝对错误。不要将DI容器放在物体中;他们不需要知道或关心他们是否被注射。这与“不打电话给我们”并不相符;我们打电话给你。"

另一种方式是:整个应用程序知道DI引擎,但随后它从中获取所需的bean。

我想你可能会认为注释会改变一些关系,因为现在豆知道他们联系在一起的事实。但是当配置被外部化为XML时,豆子就不知道DI了。

答案 1 :(得分:2)

这是一种反模式,我敢打赌你还没有为你的代码编写测试,这真的很糟糕。

当你开始编写测试时,你会发现你正在编写不可测试的代码,而你是:

  • 使用服务定位器反模式

  • 您违反了得墨忒耳法

  • 您没有遵循单一责任原则

  • 您正在隐藏对象的真实依赖关系(不使用依赖关系注入模式)

  • 在任何应用程序中,两个大堆的对象之间没有真正的分离:

    • 业务对象:责任是业务逻辑,域抽象
    • 布线和构建对象:责任是构建对象图

您希望为组件编写单元测试的那一天您会后悔这个决定,您将重构代码或编写集成测试而不是简单的单元测试(创建测试容器并将mocks注入此容器)

我的建议是阅读本指南以编写可测试的代码:(这是在谷歌工作的人使用的指南)

http://misko.hevery.com/code-reviewers-guide/

如果您愿意,可以从Misko Hevery的这些视频开始,了解测试和清洁代码会谈的心理学:

http://www.youtube.com/watch?v=wEhu57pih5w&feature=player_embedded

http://www.youtube.com/watch?v=RlfLCWKxHJ0&feature=player_embedded

http://www.youtube.com/watch?v=-FRm3VPhseI&feature=player_embedded