Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是Guice';他被邪恶所实施?在某些情况下是否合适?_Java_Guice - Fatal编程技术网

Java 是Guice';他被邪恶所实施?在某些情况下是否合适?

Java 是Guice';他被邪恶所实施?在某些情况下是否合适?,java,guice,Java,Guice,我听说过“是邪恶的”,理由是它打破了DI概念,让接口意识到它的实现者 在某些情况下,这可能是正确的,但我经常发现,这只会导致更干净的代码(不再需要维护模块),而不会真正损害过程中的任何东西 作为实用主义者,而不是纯粹主义者,您认为什么时候值得使用@ImplementedBy?您通常应该更喜欢显式绑定而不是即时(JIT)绑定。显式绑定允许注入器在注入器创建时对依赖关系图进行爬网。这允许Guice在依赖项丢失或无效时快速失败。使用像@ImplementedBy这样的即时绑定,Guice在执行绑定之前

我听说过“是邪恶的”,理由是它打破了DI概念,让接口意识到它的实现者

在某些情况下,这可能是正确的,但我经常发现,这只会导致更干净的代码(不再需要维护模块),而不会真正损害过程中的任何东西


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

您通常应该更喜欢显式绑定而不是即时(JIT)绑定。显式绑定允许注入器在注入器创建时对依赖关系图进行爬网。这允许Guice在依赖项丢失或无效时快速失败。使用像@ImplementedBy这样的即时绑定,Guice在执行绑定之前无法报告问题


JIT绑定与PrivateModules/子注入器的交互也很差。虽然大多数应用程序不需要这些功能,但当你这样做时,如果每个绑定都属于一个特定的模块,那么就不会那么痛苦了。

我对@ImplementedBy有同样的呃,呃,恶心的感觉,但同时,它非常有用。Spring必须扫描您给它的包列表中的所有类。在Guice中,您不必配置要扫描的包列表,@ImplementedBy是关键(如果不使用绑定器绑定)。当它在第一个Injector.getInstance上执行您的对象继承权限并点击一个接口时,它会使用@ImplementedBy查找默认实现(只要绑定器中没有任何内容覆盖该默认值)

我们也使用@ImplementedBy。我们发现它使用起来非常好,有点不对劲,但它很好地工作,而且由于它是DI,它实际上并不取决于实现,因为您可以用新的绑定覆盖绑定


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

我可以理解谷歌为什么会这样做,但拥有一个更喜欢的实现并不一定是坏事。注意,文档中说它是用于默认实现的,而不是唯一的实现

顺便说一句,我发现这个问题是因为我在互联网上搜索@ImplementedBy概念的现有实现

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


注释允许我用一行注释和装饰器内的一行代码泛化一些非常粗糙的生成器。对于这样一个简单的操作,我不必使用依赖关系框架。

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

对我来说,是的,如果你用它来硬连接绑定,并且永远不会重用绑定,那是很糟糕的,因为你颠倒了接口的意义。我同意@thSoft的说法,这是一种非常常见的模式,但我甚至不清楚为什么我们没有
@Implements
注释。 另外,给定的默认实现不是运行时使用的实现,这可能会让人恼火

只是想弄清楚什么

!!它还排除了通用接口,如

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

public class MyImpl implements MyInterface<String, Integer> {}
@ImplementedBy(MyImpl.class)
公共接口MyInterface{}
公共类MyImpl实现MyInterface{}
通常不会只实现一次。
详情请参阅。

这肯定与谷歌的“不作恶”格言不符?没有
@实现的原因在于它毫无意义:1。可能有多个用
@Implements(MyInterface.class)
注释的类,然后您就丢失了。2.更糟糕的是,为了找到实现,必须首先加载所有类关于泛型,我想,
@ImplementedBy
只是一个简单用法的捷径,所以它已经足够好了。顺便说一句,没有办法将
TypeToken
用作注释参数。可能有多个实现者,但如果使用正确,它仍然很有用。人们可以将它命名为
@DefaultImplementor
,以更明确地确定它是否可以使用
@ImplementedBy
在后台有构建系统时会创建循环依赖关系。通过类路径是一次性启动成本。我不喜欢
@ImplementedBy
的一点是它创建了一个循环依赖项。我本来希望有一个
@ImplementorFor
。没错,但是ImplementedFor在启动时会非常昂贵,因为您必须“查找”ImplementedFor类,这意味着扫描每个类。Hibernate有这个问题,然后他们提出了一个令人讨厌的解决办法,只扫描带有meta.xml文件的JAR,因为这很昂贵……扫描所有JAR并不理想。我同意这个理论,但在我看来,实用性占上风@MihaiDanilaBut在启动时扫描整个类路径是否不切实际?我认为这取决于应用程序,对于一个系统来说,启动成本通常很大。当然,有些事情应该由库的用户决定,库为我们提供了使用该功能的选项。是的,我想如果您没有这样做,我们可以为每台服务器都这样做,因此对于我们所做的任何服务器,让测试套件永远花费时间是不切实际的。我们的服务器启动时间很快,我们的测试套件保持这种状态(我们可以像任何人一样进行重构)
@ImplementedBy(MyImpl.class)
public interface MyInterface<SIn,SOut> {}

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