依赖项注入容器的好处是什么? [英] What are the benefits of dependency injection containers?

查看:116
本文介绍了依赖项注入容器的好处是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解依赖注入本身的好处.让我们以Spring为例.我还了解其他Spring功能(如AOP,各种帮助程序等)的好处.我只是想知道XML配置的好处是什么,例如:

I understand benefits of dependency injection itself. Let's take Spring for instance. I also understand benefits of other Spring featureslike AOP, helpers of different kinds, etc. I'm just wondering, what are the benefits of XML configuration such as:

<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代码,例如:

compared to plain old java code such as:

Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);

,它更容易调试,检查了编译时间,并且仅懂Java的任何人都可以理解. 那么,依赖注入框架的主要目的是什么? (或一段显示其优点的代码.)

which is easier debugged, compile time checked and can be understood by anyone who knows only java. So what is the main purpose of a dependency injection framework? (or a piece of code that shows its benefits.)

更新:
如果是

UPDATE:
In case of

IService myService;// ...
public void doSomething() {  
  myService.fetchData();
}

如果存在多个IoC框架,我该如何猜测我要注入的myService的哪种实现?如果给定接口只有一个实现,而我让IoC容器自动决定使用它,则在出现第二个实现后,它将被破坏.而且,如果有意仅使用一种可能的接口实现,则无需注入该接口.

How can IoC framework guess which implementation of myService I want to be injected if there is more than one? If there is only one implementation of given interface, and I let IoC container automatically decide to use it, it will be broken after a second implementation appears. And if there is intentionally only one possible implementation of an interface then you do not need to inject it.

看到IoC的一小部分配置会显示出它的好处,这将真的很有趣.我已经使用Spring一段时间了,我无法提供这样的示例.而且我可以显示单行代码,这些代码说明了休眠,dwr和我使用的其他框架的好处.

It would be really interesting to see small piece of configuration for IoC which shows it's benefits. I've been using Spring for a while and I can not provide such example. And I can show single lines which demonstrate benefits of hibernate, dwr, and other frameworks which I use.

更新2:
我意识到,无需重新编译即可更改IoC配置.真的是个好主意吗?我可以理解,当有人想更改数据库凭据而无需重新编译时-他可能不是开发人员.在您的实践中,除开发人员外,其他人多久更改一次IoC配置?我认为对于开发人员,无需更改特定的类就可以重新编译该特定类.对于非开发人员,您可能希望使他的生活更轻松,并提供一些更简单的配置文件.

UPDATE 2:
I realize that IoC configuration can be changed without recompiling. Is it really such a good idea? I can understand when someone wants to change DB credentials without recompiling - he may be not developer. In your practice, how often someone else other than developer changes IoC configuration? I think that for developers there is no effort to recompile that particular class instead of changing configuration. And for non-developer you would probably want to make his life easier and provide some simpler configuration file.

更新3:

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

External configuration of mapping between interfaces and their concrete implementations

使它具有延展性有什么好处?您不必将所有代码都置于外部,但可以肯定地将它放在ClassName.java.txt文件中,可以即时读取和手动进行编译-哇,您避免了重新编译.为什么要避免编译?!

What is so good in making it extenal? You don't make all your code external, while you definitely can - just place it in ClassName.java.txt file, read and compile manually on the fly - wow, you avoided recompiling. Why should compiling be avoided?!

之所以节省编码时间,是因为您声明性地提供了映射,而不是使用过程代码

You save coding time because you provide mappings declaratively, not in a procedural code

我知道有时声明式方法可以节省时间.例如,我仅声明一次bean属性与DB列之间的映射,并且hibernate在加载,保存,构建基于HSQL的SQL等方式时使用此映射.这是声明性方法起作用的地方.在Spring的情况下(在我的示例中),声明具有更多的行,并且与相应的代码具有相同的表现力.如果有这样的声明比代码短的例子,我想看看.

I understand that sometimes declarative approach saves time. For example, I declare only once a mapping between a bean property and a DB column and hibernate uses this mapping while loading, saving, building SQL based on HSQL, etc. This is where the declarative approach works. In case of Spring (in my example), declaration had more lines and had the same expressiveness as corresponding code. If there is an example when such declaration is shorter than code - I would like to see it.

控制反转原理可以轻松进行单元测试,因为您可以用假的实例替换实际的实现(例如用内存中的实例替换SQL数据库)

Inversion of Control principle allows for easy unit testing because you can replace real implementations with fake ones (like replacing SQL database with an in-memory one)

我确实了解控制权的倒置(我更喜欢将这里讨论的设计模式称为依赖注入",因为IoC更通用-有许多种控制方式,而我们仅将其中一种倒置-初始化控制) .我在问为什么有人需要编程语言以外的东西.我绝对可以使用代码将真实的实现替换为假的实现.而且此代码将表示与配置相同的内容-它将仅使用伪值初始化字段.

I do understand inversion of control benefits (I prefer to call the design pattern discussed here as Dependency Injection, because IoC is more general - there are many kinds of control, and we are inverting only one of them - control of initialization). I was asking why someone ever needs something other than a programming language for it. I definitely can replace real implementations with fake ones using code. And this code will express same thing as configuration - it will just initialize fields with fake values.

mary = new FakeFemale();

我确实了解DI的好处.与配置相同功能的代码相比,我不了解外部XML配置可以带来哪些好处.我认为不应避免进行编译-我每天都在编译,但我还活着.我认为DI的配置是声明式方法的不良示例.如果声明一次,并且以不同的方式多次使用,例如hibernate cfg,则声明很有用.例如,休眠属性cfg,其中bean属性和DB列之间的映射用于保存,加载,构建搜索查询等.SpringDI配置可以轻松转换为像在此问题开头一样配置代码,可以吗?而且它仅用于bean初始化,不是吗?这意味着声明性方法不会在此处添加任何内容,是吗?

I do understand benefits of DI. I do not understand what benefits are added by external XML configuration compared to configuring code that does the same. I do not think that compiling should be avoided - I compile every day and I'm still alive. I think configuration of DI is bad example of declarative approach. Declaration can be useful if is declared once AND is used many times in different ways - like hibernate cfg, where mapping between bean property and DB column is used for saving, loading, building search queries, etc. Spring DI configuration can be easily translated to configuring code, like in the beginning of this question, can it not? And it is used only for bean initialization, isn't it? Which means a declarative approach does not add anything here, does it?

当我声明休眠映射时,我只是给休眠提供了一些信息,并且基于它进行工作-我不告诉它怎么做.如果是春天,我的声明会告诉spring到底该做些什么-那么为什么要声明它,为什么不这样做呢?

When I declare hibernate mapping, I just give hibernate some information, and it works based on it - I do not tell it what to do. In case of spring, my declaration tells spring exactly wht to do - so why declare it, why not just do it?

最后更新:
伙计们,有很多答案告诉我有关依赖注入的知识,我知道这很好. 问题是关于DI配置的目的,而不是初始化代码-我倾向于认为初始化代码更短,更清晰. 到目前为止,我对问题的唯一答案是,当配置更改时,它避免了重新编译.我想我应该提出另一个问题,因为这对我来说是个大秘密,为什么在这种情况下应避免编译.

LAST UPDATE:
Guys, a lot of answers are telling me about dependency injection, which I KNOW IS GOOD. The question is about purpose of DI configuration instead of initializing code - I tend to think that initializing code is shorter and clearer. The only answer I got so far to my question, is that it avoids recompiling, when the configuration changes. I guess I should post another question, because it is a big secret for me, why compiling should be avoided in this case.

推荐答案

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

For myself one of the main reasons to use an IoC (and make use of external configuration) is around the two areas of:

  • 测试
  • 生产维护

测试

如果将测试分为3种情况(在大规模开发中这是很正常的话):

If you split your testing into 3 scenarios (which is fairly normal in large scale development):

  1. 单元测试
  2. 集成测试
  3. 黑匣子测试

您要针对的是最后两个测试场景(集成和黑盒),而不会重新编译应用程序的任何部分.

What you will want to do is for the last two test scenarios (Integration & Black box), is not recompile any part of the application.

如果您的任何测试方案都要求您更改配置(即:使用另一个组件来模拟银行集成或执行性能负载),则可以轻松地进行处理(这确实具有配置DI的好处)不过是IoC的一面.

If any of your test scenarios require you to change the configuration (ie: use another component to mimic a banking integration, or do a performance load), this can be easily handled (this does come under the benefits of configuring the DI side of an IoC though.

另外,如果您的应用程序在多个站点(具有不同的服务器和组件配置)上使用,或者在实时环境中具有更改的配置,则可以在以后的测试阶段中验证该应用程序将处理这些更改.

Additionally if your app is used either at multiple sites (with different server and component configuration) or has a changing configuration on the live environment you can use the later stages of testing to verify that the app will handle those changes.

生产

作为开发人员,您(也不应该)控制生产环境(尤其是在将您的应用分发给多个客户或单独的站点时),这对我来说是同时使用IoC的真正好处和外部配置,因为可以由基础结构/生产支持来调整和调整实时环境,而不必回到开发人员手中并通过测试(他们只想移动一个组件就需要更高的成本).

As a developer you don't (and should not) have control of the production environment (in particular when your app is being distributed to multiple customers or seperate sites), this to me is the real benefit of using both an IoC and external configuration, as it is up to the infrastructure/production support to tweak and adjust the live environment without having to go back to developers and through test (higher cost when all they want to do is move a component).

摘要

IoC的外部配置的主要好处来自赋予其他人(非开发人员)配置应用程序的能力,以我的经验,这仅在少数情况下才有用:

The main benefits that external configuration of an IoC come from giving others (non-developers) the power to configure your application, in my experience this is only useful under a limited set of circumstances:

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

在实践中,我发现即使开发出您可以控制环境的东西,随着时间的流逝,最好还是让其他人来更改配置:

In practice I've found that even when developing something that you do have control over the environment it will be run on, over time it is better to give someone else the capabilities to change the configuration:

  • 开发时,您不知道它何时会更改(该应用程序非常有用,您的公司将其出售给其他人).
  • 我不想每次请求轻微更改时都停留在更改代码上,这可以通过设置和使用良好的配置模型来解决.

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

Note: Application refers to the complete solution (not just the executable), so all files required for the application to run.

这篇关于依赖项注入容器的好处是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆