【发布时间】:2015-09-03 11:51:51
【问题描述】:
在过去十年左右的时间里,我一直在为我的 Java 实用程序类使用以下模式。该类仅包含静态方法和字段,声明为final,因此无法扩展,并且具有private 构造函数,因此无法实例化。
public final class SomeUtilityClass {
public static final String SOME_CONSTANT = "Some constant";
private SomeUtilityClass() {}
public static Object someUtilityMethod(Object someParameter) {
/* ... */
return null;
}
}
现在,随着 Java 8 中 static methods in interfaces 的引入,我最近发现自己在使用实用程序接口模式:
public interface SomeUtilityInterface {
String SOME_CONSTANT = "Some constant";
static Object someUtilityMethod(Object someParameter) {
/* ... */
return null;
}
}
这让我摆脱了构造函数,以及许多隐含在接口中的关键字(public、static、final)。
这种方法有什么缺点吗?使用实用程序类而不是实用程序接口有什么好处吗?
【问题讨论】:
-
@SotiriosDelimanolis:它将类的实现细节放入类的公共 API 中。我相信存在静态导入的具体原因之一是让人们不太愿意这样做。 Oracle documentation on static imports 特别指出常量接口反模式是一个非常糟糕的主意。
-
我还没有完全相信......如果接口没有公开任何抽象方法。但这实际上并不重要,因为这些方法不是继承的。我真的不想只为这些领域而经历所有这些。
-
作为人本人(Joshua Bloch;将常量接口创造为反模式的人):“API 应该易于使用且难以误用。它应该容易做简单的事情;可能做复杂的事情;做错事是不可能的,或者至少是困难的”。根据我对少数使用常量接口(例如 ASM)的主流 API 的经验,我一直发现实现接口(来自 ASM 的操作码)比编写静态导入更容易。我想这取决于你对设计的严格程度
-
@Vince Emigh:这取决于您使用/配置 IDE 的能力。在最好的情况下,IDE 会自动建议您使用常量并在必要时插入
import static,但它绝不会建议您使用implement和实际上并未用作真实类型的interface(没有启发式提示IDE)。 -
请注意,您可以通过在其签名中添加一个包含对非
public类型的引用的抽象方法来防止interface的任意实现。然后,包外的实现是不可能的。然而,这并不能提高清晰度,因为抽象方法将出现在publicAPI 中,开发人员会开始怀疑该方法的目的,当通过尝试实现接口的可能性来发现时,他们会认为必须有一个错误。
标签: java class interface java-8 utility-method