代码之家  ›  专栏  ›  技术社区  ›  Kevin Pang

什么时候使用依赖注入?

  •  16
  • Kevin Pang  · 技术社区  · 16 年前

    我最近一直在使用结构图,并且非常喜欢这种体验。然而,我可以看到,一个人如何能够轻松地将所有东西与接口连接起来,并最终得到将大量接口引入其构造函数的类。尽管在使用依赖注入框架时,这并不是一个大问题,但它仍然认为有些属性确实不需要仅仅为了接口而进行接口连接。

    你在哪里画出一条线来说明什么是接口,而不仅仅是向类中添加一个属性?

    9 回复  |  直到 16 年前
        1
  •  9
  •   Will    16 年前

    想想你的设计。DI允许您通过配置更改来更改代码的工作方式。它还允许您打破类之间的依赖关系,以便更容易地隔离和测试对象。你必须确定这在哪里有意义,在哪里没有意义。没有帕特的答案。

    一个好的经验法则是,如果太难测试,那么就存在一些关于单一责任和静态依赖性的问题。将执行单个函数的代码隔离到类中,并通过提取接口和使用DI框架在运行时注入正确的实例来打破静态依赖关系。通过这样做,您可以轻松地分别测试这两个部分。

        2
  •  22
  •   rism    12 年前

    依赖注入的主要问题是,虽然它提供了松散耦合的体系结构的外观,但它确实没有。

    您真正要做的是将耦合从编译时移动到运行时,但是如果类A需要一些接口B来工作,那么仍然需要提供实现接口B的类的实例。

    依赖项注入只能用于需要动态更改而不重新编译基代码的应用程序部分。

    使用我认为对控制模式反转有用的:

    • 插件架构。因此,通过创建正确的入口点,您可以为必须提供的服务定义契约。
    • 类似工作流的架构。您可以在其中动态连接多个组件,将一个组件的输出连接到另一个组件的输入。
    • 每个客户端应用程序。假设您有各种各样的客户,他们为您的项目的一组“特性”买单。通过使用依赖注入,您可以轻松地只提供核心组件和一些“添加的”组件,这些组件只提供客户已经支付的功能。
    • 翻译。尽管这通常不是为了翻译,但是您可以根据应用程序的需要“注入”不同的语言文件。根据需要,包括RTL或LTR用户界面。
        3
  •  8
  •   user JaredPar    13 年前

    依赖项注入只能用于 需要在不重新编译的情况下动态更改的应用程序 基本码

    应该使用DI将代码与外部资源(数据库、Web服务、XML文件、插件体系结构)隔离开来。如果您要测试依赖数据库的组件,那么在许多公司中,用代码测试逻辑所需的时间几乎是不允许的。

    在大多数应用程序中,数据库不会动态变化(尽管它可以),但一般来说,最好不要将应用程序绑定到特定的外部资源。改变资源所涉及的数量应该很低(数据访问类的循环复杂度应该很少超过其方法中的循环复杂度)。

        4
  •  2
  •   Chris Marasti-Georg Scott Weinstein    16 年前

    “只是向类中添加属性”是什么意思?

    我的经验法则是使类单元可测试。如果您的类依赖于另一个类的实现细节,那么需要重构/抽象到可以单独测试这些类的程度。

    编辑:您在构造函数中提到了大量接口。我建议改用setters/getter。我发现从长远来看,它使维护工作变得容易得多。

        5
  •  2
  •   chakrit Dutchie432    16 年前

    只有当它有助于分离关注点时,我才会这样做。

    像跨项目一样,我将为我的一个库项目中的实现者提供一个接口,实现项目将注入他们想要的任何特定实现。

    但这就是问题所在…所有其他情况下,它只会使系统变得不必要的复杂

        6
  •  1
  •   Gishu    16 年前

    即使有世界上所有的事实和过程……每一个决定都归结为一个判断——忘了我在哪里读到的。
    我认为这更像是一个体验/飞行时间的电话。 基本上,如果您将依赖项视为可能在不久的将来被替换的候选对象,请使用依赖项注入。如果我将“classa及其依赖项”视为替换的一个块,那么我可能不会将di用于a的deps。

        7
  •  1
  •   Harpreet    16 年前

    最大的好处是它将帮助您理解甚至发现应用程序的体系结构。您将能够非常清楚地看到您的依赖链是如何工作的,并且能够在不需要您更改无关内容的情况下对各个部分进行更改。最终将得到一个松散耦合的应用程序。这将推动您进入一个更好的设计,当您可以继续改进时,您会感到惊讶,因为您的设计将帮助您继续分离和组织代码。它还可以促进单元测试,因为您现在有了一种替代特定接口实现的自然方法。

    有些应用程序已经被抛弃了,但是如果有疑问,我会继续创建接口。经过一些练习,这不是什么负担。

        8
  •  0
  •   flipdoubt    16 年前

    我的另一个摔跤项目是 我应该在哪里使用依赖注入? 你对结构图的依赖在哪里?仅在启动应用程序中?这是否意味着所有的实现都必须从最顶层一直到最底层?

        9
  •  0
  •   George Mauer    16 年前

    我用的是温莎城堡(Castle Windsor)/微核(Microkernel),我对其他东西没有经验,但我非常喜欢。

    至于你如何决定注射什么?到目前为止,下面的经验法则对我很有帮助:如果类非常简单,不需要单元测试,您可以随意在类中实例化它,否则您可能希望通过构造函数拥有依赖性。

    至于您是否应该创建一个接口,而不是将方法和属性虚拟化,我认为您应该走接口路线,如果您a)可以看到类在不同的应用程序(即记录器)中具有某种程度的可重用性,或者b)如果是因为构造函数参数的数量,或者是因为有一个重要的蚂蚁数量的逻辑在构造函数中,否则类是很难模仿的。