tho*_*i56 25
嗯,它们不完全可比.您将始终必须通过在某个时刻实例化类来创建新对象.依赖注入还需要创建新对象.
当您想要控制或验证您使用或想要测试的类所使用的实例的行为时,依赖注入确实起作用.(对于测试驱动开发依赖注入是除最小示例之外的任何关键).
假设一个类Holder,它需要一个Handle类的对象.传统的方法是让Holder实例创建并拥有它:
class Holder {
private Handle myHandle = new Handle();
public void handleIt() {
handle.handleIt();
}
}
Run Code Online (Sandbox Code Playgroud)
Holder实例创建myHandle,类外的任何人都无法获得它.在某些情况下,单元测试正在进行,这是一个问题,因为在不创建Handle实例的情况下测试Holder类是不可能的,而Handle实例又可能依赖于许多其他类和实例.这使得测试变得笨拙和麻烦.
通过注入Handle实例,例如在构造函数中,来自外部的人负责创建实例.
class Holder {
private Handle myHandle;
public Holder(Handle injectedHandle) {
myHandle = injectedHandle;
}
public void handleIt() {
handle.handleIt();
}
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,代码几乎是相同的,而Handle仍然是私有的,但Holder类现在有一个与其外部世界耦合的失败者,这使得许多事情更简单.在测试Holder类时,可以注入模拟或存根对象而不是实例,从而可以验证或控制Holder,其调用者和句柄之间的交互.
实际注射将在其他地方进行,通常是一些"主要"程序.有多个框架可以帮助您在没有编程的情况下实现这一点,但实际上这是"主"程序中的代码:
...
private Handle myHandle = new Handle(); // Create the instance to inject
private Handler theHandler = new Handler(myHandle); // Inject the handle
...
Run Code Online (Sandbox Code Playgroud)
从本质上讲,注射只不过是一种奇特的set方法.当然,您可以使用它来实现注入机制,而不是像上面的简单示例那样在构造函数中实现.
f1s*_*1sh 16
好吧,创建一个新对象就像它可以获得的一样明确 - 你创建了一个所需类的新实例.
依赖注入是一种为您提供所需参考的机制.想象一个代表数据库连接池的类 - 通常只有该类的一个实例.现在,您需要将该引用分发给使用它的所有类.这里是依赖注入派上用场的地方 - 通过使用像Eclipse这样的DI框架,您可以定义池的一个实例将被注入需要它的类中.
您的问题本身并不容易回答,因为无法轻易地比较对象和依赖注入的创建...
Pet*_*hev 16
当然两者都创造了对象.不同之处在于谁负责创作.它是需要其依赖项的类还是像Spring这样的容器,它连接组件依赖项.您可以在单独的(通常为XML)配置文件中配置依赖项.
这实际上是一个关注点的分离.该课程说我需要这个,这个和这个组件所以我正常运作.该课程并不关心它如何获得它的组件.您可以使用单独的配置文件将它们插入到类中.
举个例子,我们可以考虑购买一个需要支付模块的购物类.您不想硬编码将使用哪个付款模块.为实现此目的,您可以反转控件.您可以在容器的配置文件中通过几次击键来更改使用的付款模块.权力是你没有接触任何Java代码.
依赖注入为您的应用程序添加了一层可配置性。从某种意义上说,当您对对象构造进行硬编码时,您需要重新构建和重新部署您的应用程序,但是当您使用依赖项注入时,您可以重新配置 XML 并更改行为,而无需重新构建和重新部署。在很多用例中,这可以节省大量的麻烦和精力。