我听说过“@ImplementedBy是邪恶的”,理由是它会破坏DI概念并使界面了解其实现者。
在某些情况下可能会出现这种情况,但我经常发现它只会导致更清晰的代码(没有很长的模块可以维护),而不会真正伤害过程中的任何内容。
作为语用学,而不是纯粹主义者,你认为什么时候使用@ImplementedBy是值得的?
答案 0 :(得分:10)
我和@ImplementedBy同时感受到了同样的呃,ick,yuck的感觉,它非常有用。 Spring必须扫描你提供的包列表中的所有类。在Guice中,您不必配置要扫描的包列表,@ ImplementedBy是关键(如果不使用Binder进行绑定)。当它在第一个Injector.getInstance上关闭你的对象heirarchy,然后命中一个接口,它然后使用@ImplementedBy找到默认实现(只要Binder中没有任何内容覆盖该默认值)。
我们也使用@ImplementedBy。我们发现它非常好用,它有点笨,但它只是工作和工作很好,因为它是DI,它实际上并不依赖于实现,因为你可以用新的覆盖绑定。
同时,DI框架通常越来越少地使用接口。所有DAO接口都在我们的项目上消失了,我们仍然可以为DAO交换模拟对象。 java类是隐含的接口,可以在不需要接口的情况下进行模拟。我们现在保留主api的接口使用非常清晰,并且不会使用实现代码混乱。对于DAO,我们不再需要它了。
答案 1 :(得分:9)
您通常应该优先考虑对即时(JIT)绑定的显式绑定。显式绑定允许注入器在注入器创建时爬行依赖图。如果依赖项缺失或无效,这允许Guice快速失败。使用像@ImplementedBy这样的即时绑定,Guice无法在执行绑定之前报告问题。
JIT绑定与PrivateModules /子注入器的交互也很差。虽然大多数应用程序不需要这些功能,但是如果每个绑定属于特定模块,那么当您执行此操作时不会那么痛苦。
答案 2 :(得分:5)
当接口不打算具有多个实现但必须是依赖注入过程的一部分时,它很有用,因为它具有必须由框架注入的依赖项。
答案 3 :(得分:3)
我可以看到为什么谷歌会做他们所做的事情,但是有一个优先实施的东西并不一定是邪恶的。请注意,文档说它适用于默认实现,而不是仅实现。
Btw,我发现了这个问题,因为我正在互联网上搜索@ImplementedBy概念的现有实现。我创建了一个名为@ImplementedBy的注释,放在我的一个接口上。当使用纯粹的,未注入的反射时,这是告诉接口使用什么实现的最简单方法,尤其是在使用仅了解接口的现有API时。 (界面,不实施)
注释允许我通过一行注释和装饰器内的一行来泛化一些非常粗糙的生成器。我没有必要使用依赖框架进行这么简单的操作。
答案 4 :(得分:0)
对我来说,是的,如果你使用它进行硬线绑定并且永远不会重复使用绑定它是邪恶的,因为你颠倒了界面的意义。我同意@thSoft这是一个很常见的模式,但它对我来说甚至不清楚,为什么我们没有@Implements
注释。
另外,给定的默认实现不是在运行时使用的实现可能会令人恼火。
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。