首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >依赖注入容器的好处是什么?

依赖注入容器的好处是什么?
EN

Stack Overflow用户
提问于 2008-09-25 07:37:19
回答 15查看 31.8K关注 0票数 105

我理解依赖注入本身的好处。让我们以Spring为例。我还理解其他Spring特性(如AOP )、不同类型的帮助程序等的好处。我只是想知道,XML配置的好处是什么,例如:

代码语言:javascript
复制
<bean id="Mary" class="foo.bar.Female">
  <property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
  <property name="girlfriend" ref="Mary"/>
</bean>

与普通的旧java代码相比,例如:

代码语言:javascript
复制
Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);

这是更容易调试,编译时间检查,可以理解任何人谁只懂java。那么,依赖注入框架的主要目的是什么?(或者一段显示其优点的代码。)

更新:

如果

代码语言:javascript
复制
IService myService;// ...
public void doSomething() {  
  myService.fetchData();
}

如果有多个myService,那么myService框架如何猜测要注入哪个实现呢?如果给定接口只有一个实现,并且我让IoC容器自动决定使用它,那么在出现第二个实现后,它就会中断。如果有意地只有一个接口的可能实现,那么您就不需要注入它。

看到IoC的一小块配置将是非常有趣的,这显示了它的好处。我使用Spring已经有一段时间了,我不能提供这样的例子。我可以显示一行代码,这些行演示了hibernate、dwr和我使用的其他框架的优点。

更新2:

我意识到IoC配置可以在不重新编译的情况下进行更改。这真的是个好主意吗?我可以理解什么时候有人想要更改DB凭证而不重新编译-他可能不是开发人员。在您的实践中,开发人员以外的其他人多久更改一次IoC配置?我认为对于开发人员来说,并不需要重新编译特定的类,而不是改变配置。对于非开发人员,您可能希望使他的生活更轻松,并提供一些更简单的配置文件。

更新3:

接口及其具体实现之间映射的外部配置

有什么能让它伸直的?并不是所有的代码都是外部的,当然可以--只要把它放在ClassName.java.txt文件中,手动读取和编译就行了--哇,你避免了重新编译。为什么要避免编译?!

节省编码时间是因为您以声明方式提供映射,而不是在过程代码中提供映射。

我理解有时声明式方法可以节省时间。例如,我只声明一次bean属性和DB列之间的映射,hibernate在加载、保存、构建基于HSQL的SQL时使用此映射。这就是声明式方法工作的地方。对于Spring (在我的示例中),声明有更多的行,具有与相应代码相同的表现力。如果有这样的声明比代码短的例子,我希望看到它。

控制反转原理允许简单的单元测试,因为您可以用假的实现替换实际的实现(比如用内存中的数据库替换SQL数据库)。

我确实理解控制好处的倒置(我更喜欢将这里讨论的设计模式称为依赖注入,因为IoC更一般-有很多种控制,而且我们只反转其中的一种--初始化控制)。我是在问为什么有人需要的不是一种编程语言。我肯定可以用代码用假的实现来代替真正的实现。这段代码将表示与配置相同的内容--它只会用假值初始化字段。

代码语言:javascript
复制
mary = new FakeFemale();

我理解DI的好处。我不明白与配置代码相比,外部XML配置会带来什么好处。我不认为应该避免编译--我每天都在编译,而且我还活着。我认为DI的配置是声明式方法的坏例子。如果声明只声明一次,并且多次以不同的方式使用,比如hibernate cfg,在bean属性和DB列之间的映射用于保存、加载、构建搜索查询等,则声明可能很有用。Spring DI配置可以很容易地转换为配置代码,就像在这个问题开始时一样,不是吗?它只用于bean初始化,不是吗?这意味着声明性方法不会在这里添加任何内容,对吗?

当我声明hibernate映射时,我只是给hibernate一些信息,并且它是基于hibernate工作的--我没有告诉它该做什么。如果是春天,我的声明会告诉春天该怎么做--那么为什么不直接宣布呢?

最后更新:

伙计们,很多答案都告诉我依赖注入,我知道这很好。问题在于DI配置的目的,而不是初始化代码--我倾向于认为初始化代码更短、更清晰。到目前为止,我对问题的唯一回答是,当配置发生变化时,它可以避免重新编译。我想我应该发布另一个问题,因为这对我来说是个大秘密,为什么在这种情况下应该避免编译。

EN

回答 15

Stack Overflow用户

回答已采纳

发布于 2008-10-08 12:20:02

对于我自己来说,使用IoC (并使用外部配置)的主要原因之一是围绕以下两个方面:

  • 测试
  • 生产维护

测试

如果将测试分为3种场景(这在大规模开发中是相当正常的):

  1. 单元测试
  2. 集成测试
  3. 黑箱测试

对于最后两个测试场景(Integration&Black box),您要做的是不重新编译应用程序的任何部分。

如果您的任何测试方案要求您更改配置(即:使用另一个组件来模拟银行集成,或执行性能负载),则可以很容易地处理这一点(不过,这是配置IoC的DI端的好处之一)。

此外,如果您的应用程序在多个站点(具有不同的服务器和组件配置)使用,或者在活动环境中具有更改的配置,则可以使用测试的后期阶段来验证应用程序是否会处理这些更改。

生产

作为一名开发人员,您不(也不应该)控制生产环境(特别是当您的应用程序被分发到多个客户或单独的站点时),这对我来说是使用IoC和外部配置的真正好处,因为这取决于基础设施/生产支持来调整和调整活动环境,而无需返回开发人员并通过测试(当他们只想移动组件时,成本就会更高)。

摘要

IoC的外部配置的主要好处在于让其他人(非开发人员)能够配置您的应用程序,在我的经验中,只有在有限的情况下才有用:

  • 应用程序被分发到环境不同的多个站点/客户端。
  • 对生产环境和设置的有限开发控制/输入。
  • 测试场景。

在实践中,我发现,即使在开发您确实可以控制环境的东西时,随着时间的推移,最好还是让其他人拥有更改配置的能力:

  • 当你开发的时候,你不知道它什么时候会改变(这个应用非常有用,你的公司会把它卖给别人)。
  • 我不希望每次请求更改代码时都会被困住,这可以通过设置和使用一个好的配置模型来处理。

注意:应用程序是指完整的解决方案(不仅仅是可执行的),所以应用程序运行所需的所有文件。

票数 41
EN

Stack Overflow用户

发布于 2008-09-25 08:21:37

依赖注入是一种编码风格,其根源在于观察到对象委托通常比对象继承更有用的设计模式(即对象具有--关系比对象更有用--关系)。然而,DI的另一个要素是必需的,即创建对象接口。将这两种强大的设计模式结合在一起,软件工程师很快就意识到他们可以创建灵活、松散耦合的代码,从而产生了依赖注入的概念。然而,直到对象反射在某些高级语言中可用之后,DI才真正兴起。反射组件是当今大多数DI系统的核心,因为DI真正酷的方面要求能够通过编程方式选择对象,并使用与对象本身无关的系统配置对象并将它们注入其他对象。

语言必须提供对普通面向对象编程技术的良好支持,以及对对象接口和对象反射(例如Java和C#)的支持。虽然您可以在C++系统中使用DI模式构建程序,但由于语言本身缺乏反射支持,因此无法支持应用服务器和其他DI平台,从而限制了DI模式的表现力。

使用DI模式构建的系统的优点:

  1. DI代码更容易重用,因为“依赖”功能被外推到定义良好的接口中,允许将其配置由合适的应用程序平台处理的独立对象随意插入其他对象。
  2. DI代码更容易测试。通过构建实现应用程序逻辑所期望的接口的“模拟”对象,可以在黑匣子中测试由对象表示的功能。
  3. DI码更灵活。这是与生俱来的松散耦合的代码--到了一个极端。这允许程序员选择和选择对象是如何连接的,完全基于对象一端所需的接口和另一端的表示接口。
  4. DI对象的外部(Xml)配置意味着其他人可以按不可预见的方向自定义您的代码。
  5. 外部配置也是关注模式的分离,因为对象初始化和对象相互依赖管理的所有问题都可以由应用服务器来处理。
  6. 注意,使用DI模式并不需要外部配置,对于简单的互连来说,小型构建器对象通常是足够的。两者之间在灵活性上有一种权衡。构建器对象不像外部可见的配置文件那样灵活。DI系统的开发人员必须权衡灵活性优于便利性的优点,注意在配置文件中表达的对对象构造的小规模、细粒度控制可能会增加混乱和维护成本。

当然,DI代码看起来更麻烦,让所有那些将对象配置为注入其他对象的XML文件的缺点似乎是很困难的。然而,这是DI系统的重点。您的能力,混合和匹配的代码对象作为一系列的配置设置,允许您构建复杂的系统使用第三方代码,与您的部分最低限度的编码。

问题中提供的示例仅仅触及了一个适当因素的DI对象库所能提供的表现力。通过一些实践和大量的自律,大多数DI实践者发现他们可以构建具有100%测试覆盖率的应用程序代码的系统。这一点本身就是非同寻常的。这不是一个包含几百行代码的小型应用程序的100%测试覆盖率,而是包含数十万行代码的应用程序的100%测试覆盖率。我无法描述提供此级别可测试性的任何其他设计模式。

您是正确的,因为只有10行代码的应用程序比几个对象和一系列XML配置文件更容易理解。但是,与大多数功能强大的设计模式一样,当您继续向系统添加新功能时,会发现这些优点。

简而言之,大规模的基于DI的应用程序既易于调试,又易于理解。虽然Xml配置不是“编译时检查”,但如果开发人员试图将具有不兼容接口的对象注入到另一个对象,那么作者所知道的所有应用程序服务都将向开发人员提供错误消息。而且大多数都提供了包含所有已知对象配置的“检查”功能。这是通过检查待注入对象A是否实现了对象B为所有配置的对象注入所需的接口来实现的。

票数 15
EN

Stack Overflow用户

发布于 2008-09-25 07:44:53

这是一个有点加载的问题,但我倾向于认为,大量的xml配置并没有带来多大的好处。我希望我的应用程序尽可能轻于依赖关系,包括庞大的框架。

它们在很大程度上简化了代码,但它们的复杂性也使跟踪问题变得相当困难(我亲眼目睹过这样的问题,而直接的Java处理则要舒服得多)。

我想这取决于你的风格,你对什么感到舒服.您喜欢自己的解决方案,并从中获益,还是依赖现有的解决方案,而这些解决方案在配置不正确时可能会被证明是困难的?这都是一种权衡。

然而,XML配置有点像我的宠物.我不惜一切代价去避免它。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/131975

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档