Java 创建新对象和依赖注入的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3386889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between creating new object and dependency injection
提问by TaherT
What is the difference between creating a new object and dependency injection? Please explain in detail.
创建新对象和依赖注入有什么区别?请详细说明。
采纳答案by f1sh
Well, creating a new object is as explicit as it can get - you create a new instance of the desired class.
好吧,创建一个新对象是尽可能明确的 - 您创建所需类的新实例。
Dependency injections is a mechanism that provides you with references where you need them. Imagine a class that represents a connection pool to your database - you usually only have one instance of that class. Now you need to distribute that reference to all the classes that use it. Here is where Dependency Injection comes in handy - by using a DI framework such as Spring you can define that the one instance of your pool will be injected into the classes that need it.
依赖注入是一种机制,可在您需要的地方为您提供参考。想象一个代表数据库连接池的类——您通常只有该类的一个实例。现在您需要将该引用分发给所有使用它的类。这就是依赖注入派上用场的地方 - 通过使用诸如 Spring 之类的 DI 框架,您可以定义池的一个实例将被注入到需要它的类中。
Your question itself is not easy to answer since the creation of an object and dependency injection can't be compared that easily...
您的问题本身并不容易回答,因为无法轻松比较对象的创建和依赖项注入...
回答by Bozho
When using an inversion-of-control container to perform dependency injection, the container creates the objects, and not the developer. This is done so that the container can "inject" these objects into other objects.
当使用控制反转容器执行依赖注入时,容器创建对象,而不是开发人员。这样做是为了容器可以将这些对象“注入”到其他对象中。
回答by Petar Minchev
Of course both create objects. The difference is in who is responsible for the creation. Is it the class which needs its dependencies or a container like Spring for example, which wires the components dependencies. You configure the dependencies in a separate(typically XML) configuration file.
当然,两者都创建对象。区别在于谁负责创造。是需要其依赖项的类还是像 Spring 这样的容器,它连接组件依赖项。您可以在单独的(通常是 XML)配置文件中配置依赖项。
It is really a separation of concerns. The class says I need this, this and this component so I functionate properly. The class doesn't care how it gets its components. You plug in them into the class with a separate configuration file.
这实际上是关注点分离。班级说我需要这个、这个和这个组件,这样我才能正常工作。该类并不关心它如何获取其组件。您可以使用单独的配置文件将它们插入到类中。
To give you an example lets consider having a shopping class which needs a payment module. You don't want to hardcode which payment module will be used. To achieve this you inverse the control. You can change the used payment module with a few keystrokes in the configuration file of the container. The power is that you aren't touching any Java code.
举个例子,让我们考虑一个需要支付模块的购物类。您不想硬编码将使用哪个支付模块。为了实现这一点,您可以反转控制。您可以在容器的配置文件中通过几次按键更改使用的支付模块。强大之处在于您无需接触任何 Java 代码。
回答by thoni56
Well, they're not exactly comparable. You will always have to create a new object by instantiating a class at some point. Dependency injection also requires creating new objects.
好吧,它们并不完全具有可比性。您将始终必须通过在某个时刻实例化一个类来创建一个新对象。依赖注入还需要创建新对象。
Dependency injection really comes into play when you want to control or verify the behavior of instances used by a class that you use or want to test. (For Test Driven Development, dependency injection is key for all but the smallest example).
当您想要控制或验证您使用或想要测试的类所使用的实例的行为时,依赖注入真正发挥作用。(对于测试驱动开发,除了最小的示例之外,依赖注入是所有其他项目的关键)。
Assume a class Holder which requires an object of class Handle. The traditional way to do that would be to let the Holder instance create and own it:
假设一个类 Holder 需要一个类 Handle 的对象。传统的方法是让 Holder 实例创建并拥有它:
class Holder {
private Handle myHandle = new Handle();
public void handleIt() {
handle.handleIt();
}
}
The Holder instance creates myHandle and no one outside the class can get at it. In some cases, unit-testing being one of them, this is a problem because it is not possible to test the Holder class without creating the Handle instance which in turn might depend on many other classes and instances. This makes testing unwieldy and cumbersome.
Holder 实例创建了 myHandle 并且类之外的任何人都无法获得它。在某些情况下,单元测试就是其中之一,这是一个问题,因为在不创建 Handle 实例的情况下无法测试 Holder 类,而 Handle 实例又可能依赖于许多其他类和实例。这使得测试变得笨拙和麻烦。
By injecting the Handle instance, for example in the constructor, someone from the outside becomes responsible for the creation of the instance.
通过注入 Handle 实例,例如在构造函数中,外部人员将负责创建该实例。
class Holder {
private Handle myHandle;
public Holder(Handle injectedHandle) {
myHandle = injectedHandle;
}
public void handleIt() {
handle.handleIt();
}
}
As you can see the code is almost the same, and the Handle is still private, but the Holder class now has a much loser coupling to its outside world which makes many things simpler. And when testing the Holder class a mock or stub object can be injected instead of a real instance making it possible to verify or control the interaction between the Holder, its caller and the handle.
如您所见,代码几乎相同,并且 Handle 仍然是私有的,但是 Holder 类现在与其外部世界的耦合更加失败,这使许多事情变得更简单。并且在测试 Holder 类时,可以注入模拟或存根对象而不是真实实例,从而可以验证或控制 Holder、其调用者和句柄之间的交互。
The actual injection would take place at some other place, usually some "main" program. There are multiple frameworks that can help you do that without programming, but essentially this is the code in the "main" program:
实际的注入会发生在其他地方,通常是某个“主”程序。有多种框架可以帮助您在不编程的情况下做到这一点,但本质上这是“主”程序中的代码:
...
private Handle myHandle = new Handle(); // Create the instance to inject
private Handler theHandler = new Handler(myHandle); // Inject the handle
...
In essence, the injection is nothing more than a fancy set
method. And of course, you can implement the injection mechanism using that instead of in the constructor like the simple example above.
本质上,注入无非是一种花哨的set
方法。当然,您可以使用它来实现注入机制,而不是像上面的简单示例那样在构造函数中实现。
回答by carlsborg
Dependency injections adds a layer of configurability into your application. In the sense, when you hard code object construction, you need to re-build and re-deploy your app, but when you use dependency injection, you can re configure the XML and change the behavior without re-building and re-deploying. There are a large variety of use cases where this can save a lot of tie and effort.
依赖注入为您的应用程序添加了一层可配置性。从某种意义上说,当您硬编码对象构建时,您需要重新构建和重新部署您的应用程序,但是当您使用依赖注入时,您可以重新配置 XML 并更改行为,而无需重新构建和重新部署。有各种各样的用例,这可以节省大量的关系和精力。
回答by wjohnson
The answer to the following question may also give the answer you are looking for: Why is the new operator an anti-pattern? Well, the simple answer is that using the new operator may create a hidden, inaccessible dependency within the containing class. This makes testing the containing class more difficult because it involves testing the hidden dependency at the same time (barring MOCK frameworks of course). However, you can avoid this situation by not using the new operator and injecting the dependent object instead. This also has the following advantages:
以下问题的答案也可能给出您正在寻找的答案:为什么新运算符是反模式?嗯,简单的答案是,使用 new 运算符可能会在包含类中创建一个隐藏的、不可访问的依赖项。这使得测试包含类变得更加困难,因为它同时涉及测试隐藏的依赖项(当然 MOCK 框架除外)。但是,您可以通过不使用 new 运算符而是注入依赖对象来避免这种情况。这还具有以下优点:
- For test purposes you can inject a different object.
- The resulting containing class is more reusable because it can support different implementations of the dependent object.
- 出于测试目的,您可以注入不同的对象。
- 生成的包含类更具可重用性,因为它可以支持依赖对象的不同实现。