首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Guice的目的

Guice的目的
EN

Stack Overflow用户
提问于 2012-10-19 16:35:18
回答 2查看 1.8K关注 0票数 27

我(认为我)理解依赖注入的目的,但我只是不明白为什么我需要像Guice这样的东西来完成它(很明显,我不需要Guice,但我的意思是为什么使用它是有益的)。假设我有现有的(非Guice)代码,如下所示:

代码语言:javascript
复制
public SomeBarFooerImplementation(Foo foo, Bar bar) {
    this.foo = foo;
    this.bar = bar;
}

public void fooThatBar() {
    foo.fooify(bar);
}

在某个更高的层次,也许在我的主要(),我有:

代码语言:javascript
复制
public static void main(String[] args) {
    Foo foo = new SomeFooImplementation();
    Bar bar = new SomeBarImplementation();
    BarFooer barFooer = new SomeBarFooerImplementation(foo, bar);

    barFooer.fooThatBar();
}

现在我基本上得到了依赖注入的好处,对吗?更容易测试等等?当然,如果您想要的话,可以轻松地更改main()以从配置中获得实现类名,而不是硬编码。

据我所知,在Guice做同样的事情,我会做这样的事情:

代码语言:javascript
复制
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的方式有什么好处吗?

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-19 16:45:46

在现实生活和更大的应用程序中,组件的级别不仅仅是2(如您的示例所示)。可能是10个或更多。此外,需求和依赖关系也可能随时发生变化。

当执行“手动DI”时,这意味着必须手动更改所有组件及其传递依赖项的所有路径。这可能是相当多的工作。

使用“真正的DI”(即Guice、Spring、CDI),您只需更改一两个受影响的组件和布线(Guice上的Module )就可以了。

另外:假设您的一些深嵌套组件位于工厂中,其他组件应该调用这些组件。在Guice中,只需注入一个Provider<Foo>就可以了。手动执行时,必须将工厂的依赖项及其实例化拖到代码中。

更让人沮丧的是。

编辑来澄清最后一点:图像您有一些深嵌套逻辑(10级或更高级别)。在底部,您的逻辑将创建一个基于某些值的工厂,例如实际温度:如果“温暖”,那么需要一个Cooler,如果“冷”,则创建一个Heater。两者都有接口TemperatureAdjustorCoolerHeater都需要很多不同的依赖关系来完成他们的工作。

由于该因素的实例类型,您不能在main中创建一个,并将其传递到需要它的地方。因此,您最终会将两个工厂的依赖关系传递到需要它们的位置。(“大量依赖”加上“大量依赖”是“太多而不能保持理智”)

使用像Guice这样的“真正的DI”,您可以使用AssistedInject来避免依赖关系的混乱,并且只将实际的业务值(这里是:温度)提供给工厂并完成。工厂的接线是在模块中完成的。

票数 20
EN

Stack Overflow用户

发布于 2013-07-16 18:28:31

手工编码的DI是真正的DI。

当您考虑IOC容器的复杂性时,您必须更深入地研究为什么要使用它。我长期反对国际奥委会,能够设计和实现干净,快速,整洁的手编码,真正的DI。但是,我放弃了容器的概念,因为它们有助于标准化实现,并提供了一种更基于配置的机制,用于向依赖关系方程中添加新的决策。其他人已经为你写好了,这样你就不用花时间手工编码了。

许多人说,在大型应用程序中使用容器,在小型应用程序中使用手工代码。我说的正好相反。小应用程序的性能没有那么受限制。继续使用打包容器的实现速度。在大型应用程序中,您将花费大量时间进行优化,请考虑手动编写DI代码。

编辑:但是让我补充一下,IOC容器或手工编码,总是使用DI和代码到一个界面--不管你正在做的应用多么简单。即使在小应用程序中也要编写很好的代码。

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

https://stackoverflow.com/questions/12978609

复制
相关文章

相似问题

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