2011-06-01 68 views
11

我听说“@ImplementedBy是邪恶的”,理由是它打破了DI的概念,并使界面意识到它的实现者。Guice's @ImplementedBy邪恶?在某些情况下是否合适?

在某些情况下这可能是正确的,但是我经常发现它只是导致更干净的代码(没有长模块来维护),而不会真正伤害过程中的任何内容。

作为语用学而不是纯粹主义者,您认为使用@ImplementedBy值得什么时候?

+11

这与Google的“不要做坏事”的座右铭当然是不相容的吗? – skaffman 2011-06-01 19:28:12

回答

8

我有同样的呃,ick,yuck感觉@ImplementedBy但同时,它是非常有用的。 Spring必须扫描您提供的软件包列表中的所有类。在Guice中,您不必配置要扫描的软件包列表,并且@ImplementedBy是关键(如果不使用Binder绑定的话)。当它在第一个Injector.getInstance上落到你的对象上时,碰到一个接口,然后它使用@ImplementedBy找到默认实现(只要Binder没有覆盖该默认实现)。

我们也使用@ImplementedBy。我们发现它非常好用,有点呃,但它工作正常并且工作得很好,而且由于它是DI,所以它不是真的取决于实现,因为无论如何您都可以用新的覆盖绑定。

与此同时,接口通常在DI框架中越来越少使用。所有的DAO接口都离开了我们的项目,我们仍然可以交换DAO的模拟对象。 java类是隐式接口,可以在不需要接口的情况下进行模拟。我们现在保留主API的接口使用非常清晰,并且不会将其与实现代码混淆。对于DAO的我们不再需要这个了。

5

您通常应该更喜欢对即时(JIT)绑定的显式绑定。显式绑定允许注入器在注入器创建时抓取依赖关系图。这允许Guice在缺失或无效的情况下快速失效。使用@ImplementedBy等即时绑定,Guice无法报告问题,直到绑定被执行。

JIT绑定也与PrivateModules/child注入器交互不良。尽管大多数应用程序不应该需要这些功能,但如果每个绑定都属于特定模块,那么这样做并不那么痛苦。

2

我可以看到谷歌为什么做了他们所做的事情,但有一个首选的东西实施并不一定是邪恶的。注意文档说它是为默认执行,而不是只有之一。

顺便说一句,我发现这个问题,因为我在因特网上寻找@ImplementedBy概念的现有实现。

我创建了一个名为@ImplementedBy的注释,放置在我的一个接口上。当使用纯粹的未注入反射时,这是告诉接口要使用什么实现的最简单方法,特别是在处理仅理解接口的现有API时。 (接口,不是实现)

这个注释允许我在装饰器中用一行注释和一行代码将一些非常粗糙的生成器泛化。我不必为这种简单的操作使用依赖框架。

4

当一个接口不打算具有多个实现,但必须成为依赖注入过程的一部分时非常有用,因为它具有必须由框架注入的依赖关系。

0

对我来说,是的,如果你使用它来硬连线绑定并且永远不会重复使用绑定是邪恶的,因为你反转了界面的感觉。我同意@thSoft这是一个很常见的模式,但对我而言甚至不清楚,为什么我们没有注解。 另外,它可能令人恼火的是,给定的默认实现不是在运行时使用的实现。

只是要清楚什么google sayed to that

Annotate types tell the injector what their default implementation type is. … 

!它也忽略了通用接口,如

@ImplementedBy(MyImpl.class) 
public interface MyInterface<SIn,SOut> {} 

public class MyImpl implements MyInterface<String, Integer> {} 

通常不会只实现一次。 查看Inject Generic Implementation using Guice了解详情。

+0

没有@ @ Implements的原因是它没有任何意义:1.可能有多个类用'@Implements(MyInterface.class)'注解,然后你就会丢失。更糟糕的是,为了找到实现,你必须首先加载所有的类。 +++关于泛型,我猜'@ ImplementedBy'只是简单用法的一个捷径,所以它足够好。 AFAIK,没有办法使用'TypeToken'作为注解参数。 – maaartinus 2017-11-15 04:10:02

相关问题