DI Control-Freak反模式:理解困难

时间:2012-07-04 14:18:13

标签: .net design-patterns dependency-injection anti-patterns

我正在阅读马克·西曼(Mark Seemann)的.NET中的依赖注入(Dependency Injection),我不能为我的生活让我的头脑包围:

  

虽然关键字在涉及VOLATILE时是一种代码味道   相关内容,您无需担心将其用于STABLE   相关内容。 关键字通常不会突然“非法”,   但是你应该避免使用它来获得VOLATILE的实例   相关内容。

也许是因为我仍然不能把我的脑袋缠绕在周围的环境中,而不仅仅是一个全局变量,但我只是没有得到作者的意思。

我真的很想从上到下理解DI但是现在我被卡住了,这只是书中的1/3 ... Control-Freak反模式似乎是每个程序员曾经生活过......

任何人都有任何见解?

3 个答案:

答案 0 :(得分:8)

波动性(对我而言)衡量一个阶级需要改变的可能性。

理想情况下,您将类设计为对扩展开放但不接受修改(开放封闭原则)。这并不总是可行的。你接近改变的那些类别比其他类别更不稳定。

NDepend(.Net静态分析指标工具)有一个名为Instability的指标,在​​我看来是同义词。 他们将此定义为:

  

不稳定性(I):传出耦合(Ce)与总耦合的比率。 I = Ce /(Ce + Ca)。该指标是程序集变化弹性的指标。该指标的范围是0到1,I = 0表示完全稳定的装配,I = 1表示装配完全不稳定。

你不希望Stable类依赖于较不稳定的类。

就决定注入与否而言,这听起来更像是一个阶级角色问题。从域驱动设计(DDD)类通常是实体(它们具有身份),服务(它们协调事物)或值(它们是不可变的和可比较的,如RED或100ml)。

您将注入服务,您可以在值上调用new。实体通常来自一个存储库(您注入),但在内部存储库会调用new。这有帮助吗?

答案 1 :(得分:1)

通常DI容器将所有依赖关系解析为具体实现并为您处理生命周期。但 DI Control-Freak 确实相反:使用new关键字创建具体对象,注入它们并仅自己处理生命时间。因此,没有其他人可以在您的代码之外配置和处理依赖关系。因此,通过提供其他实现或假货来重用或测试它。

以下是来自@ mark-seemann的书的引文,它回答了你的问题:

  

我将它命名为CONTROL FREAK来描述一个不会的类   放弃对其依赖性的控制。

每次我们使用新密钥创建类型的新实例时都会发生这种情况 - 字。当我们这样做时,我们明确声明我们将控制它的生命周期 实例,没有其他人有机会拦截该特定对象。

答案 2 :(得分:1)

之前我没有听过这些术语,但转换了我对依赖注入的了解,我将它们定义如下。

稳定依赖是指具体实现在课堂或配置,时间或不同情况下不会发生变化的依赖。

易失性依赖是指具体实现可能在课程或配置,时间或不同情况下变化的依赖性。

如果您可以在Java中原谅一个示例,那么稳定的依赖关系将是StringBuilder。如果您正在编写一个构建字符串的方法,则不需要注入StringBuilder,您只需创建它即可。同上ArrayListHashMap等。除了标准库类之外,如果你正在编写一个银行应用程序,你可能不会注入RunningTotaliser,因为这是一个只增加数字的对象对你而言。

标准库中的volatile依赖项的示例更难以提出。一个典型的例子是DataSource - 这是一个封装数据库连接细节的对象,几乎肯定不会由实际建立连接的代码提供。