我(认为我)理解依赖注入的目的,但我只是不明白为什么我需要像Guice这样的东西来完成它(很明显,我不需要Guice,但我的意思是为什么使用它是有益的)。假设我有现有的(非Guice)代码,如下所示:
public SomeBarFooerImplementation(Foo foo, Bar bar) {
this.foo = foo;
this.bar = bar;
}
public void fooThatBar() {
foo.fooify(bar);
}在某个更高的层次,也许在我的主要(),我有:
public static void main(String[] args) {
Foo foo = new SomeFooImplementation();
Bar bar = new SomeBarImplementation();
BarFooer barFooer = new SomeBarFooerImplementation(foo, bar);
barFooer.fooThatBar();
}现在我基本上得到了依赖注入的好处,对吗?更容易测试等等?当然,如果您想要的话,可以轻松地更改main()以从配置中获得实现类名,而不是硬编码。
据我所知,在Guice做同样的事情,我会做这样的事情:
public SomeModule extends AbstractModule {
@Override
protected void configure() {
bind(Foo.class).to(SomeFooImplementation.class);
bind(Bar.class).to(SomeBarImplementation.class);
bind(BarFooer.class).to(SomeBarFooerImplementation.class);
}
}
@Inject
public SomeBarFooerImplementation(Foo foo, Bar, bar) {
this.foo = foo;
this.bar = bar;
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new SomeModule());
Foo foo = injector.getInstance(Foo.class);
barFooer.fooThatBar();
}是这样吗?在我看来,似乎只是语法糖,而不是特别有用的句法糖。如果将“新XxxImplementation()”的内容分解成单独的模块而不是直接在main()中执行,那么没有Guice就很容易做到这一点。
所以我觉得我错过了一些非常基本的东西。你能给我解释一下Guice的方式有什么好处吗?
提前谢谢。
发布于 2012-10-19 16:45:46
在现实生活和更大的应用程序中,组件的级别不仅仅是2(如您的示例所示)。可能是10个或更多。此外,需求和依赖关系也可能随时发生变化。
当执行“手动DI”时,这意味着必须手动更改所有组件及其传递依赖项的所有路径。这可能是相当多的工作。
使用“真正的DI”(即Guice、Spring、CDI),您只需更改一两个受影响的组件和布线(Guice上的Module )就可以了。
另外:假设您的一些深嵌套组件位于工厂中,其他组件应该调用这些组件。在Guice中,只需注入一个Provider<Foo>就可以了。手动执行时,必须将工厂的依赖项及其实例化拖到代码中。
更让人沮丧的是。
编辑来澄清最后一点:图像您有一些深嵌套逻辑(10级或更高级别)。在底部,您的逻辑将创建一个基于某些值的工厂,例如实际温度:如果“温暖”,那么需要一个Cooler,如果“冷”,则创建一个Heater。两者都有接口TemperatureAdjustor。Cooler和Heater都需要很多不同的依赖关系来完成他们的工作。
由于该因素的实例类型,您不能在main中创建一个,并将其传递到需要它的地方。因此,您最终会将两个工厂的依赖关系传递到需要它们的位置。(“大量依赖”加上“大量依赖”是“太多而不能保持理智”)
使用像Guice这样的“真正的DI”,您可以使用AssistedInject来避免依赖关系的混乱,并且只将实际的业务值(这里是:温度)提供给工厂并完成。工厂的接线是在模块中完成的。
发布于 2013-07-16 18:28:31
手工编码的DI是真正的DI。
当您考虑IOC容器的复杂性时,您必须更深入地研究为什么要使用它。我长期反对国际奥委会,能够设计和实现干净,快速,整洁的手编码,真正的DI。但是,我放弃了容器的概念,因为它们有助于标准化实现,并提供了一种更基于配置的机制,用于向依赖关系方程中添加新的决策。其他人已经为你写好了,这样你就不用花时间手工编码了。
许多人说,在大型应用程序中使用容器,在小型应用程序中使用手工代码。我说的正好相反。小应用程序的性能没有那么受限制。继续使用打包容器的实现速度。在大型应用程序中,您将花费大量时间进行优化,请考虑手动编写DI代码。
编辑:但是让我补充一下,IOC容器或手工编码,总是使用DI和代码到一个界面--不管你正在做的应用多么简单。即使在小应用程序中也要编写很好的代码。
https://stackoverflow.com/questions/12978609
复制相似问题