不使用未实现的接口来保持常量的推理?

Jam*_*hon 5 java interface constants

在他的书" Effective Java"中,Joshua Bloch建议不要使用Interfaces来保存常量,

常量接口模式是接口的不良使用.类在内部使用一些常量是一个实现细节.实现常量接口会导致此实现细节泄漏到类的导出API中.类的用户实现一个常量接口并不重要.事实上,它甚至可能使他们感到困惑.更糟糕的是,它代表了一种承诺:如果在将来的版本中修改了类以便它不再需要使用这些元素,它仍然必须实现接口以确保二进制兼容性.如果非最终类实现了一个常量接口,那么它的所有子类的命名空间都会受到接口中常量的污染.

他的推理对我来说很有意义,而且每当提出这个问题时它似乎都是流行的逻辑,但它忽略了在接口中存储常量然后不实现它们.

例如,

public interface SomeInterface {
    public static final String FOO = "example";
}

public class SomeOtherClass {
    //notice that this class does not implement anything
    public void foo() {
        thisIsJustAnExample("Designed to be short", SomeInteface.FOO);
    }
}
Run Code Online (Sandbox Code Playgroud)

我和一直使用这种方法的人一起工作.我倾向于使用带有私有构造函数的类来保存我的常量,但我已经开始以这种方式使用接口来保持代码的一致性.是否有任何理由不以我上面概述的方式使用接口?

本质上,它是一个简短的手,可以防止您必须将类设为私有,因为无法初始化接口.

Viv*_*ath 5

我想它确实起了作用,但正如朋友曾经说过的那样:"你可以尝试用章鱼拖地板;它可能会完成工作,但它不是正确的工具".

存在用于指定合同的接口,然后由类实现.当我看到一个接口时,我假设有一些实现它的类.所以我倾向于说这是滥用接口而不是使用它们的一个例子,仅仅因为我认为这不是接口的使用方式.

我想我不明白为什么这些价值观首先是公开的,如果他们只是在一个班级私下使用.为什么不把它们移到课堂上?现在,如果这些值将由一堆类使用,那么为什么不创建一个enum?我见过的另一种模式是一个只保存公共常量的类.这与您描述的模式类似.但是,这个课程可以成为最终的,以便不能扩展; 没有什么可以阻止开发人员实现你的界面.在这些情况下,我只是倾向于使用enum.

UPDATE

这将是对评论的回应,但随后它变得很长.创建一个只保存一个值的界面更加浪费!:)你应该使用私有常量.虽然将不相关的值放入单个枚举中是很糟糕的,但您可以将它们分组到单独的枚举中,或者只是为类使用私有常量.

此外,如果看起来所有这些类都共享这些不相关的常量(但在类的上下文中有意义),为什么不创建一个将这些常量定义为的抽象类protected?您所要做的就是扩展此类,您的派生类将可以访问常量.


Pet*_*rey 3

我不认为具有私有构造函数的类比使用接口更好。

引文所说的是,使用implements ConstantInterface并不是最佳实践,因为该接口成为 API 的一部分。

但是,您可以使用静态导入或限定名称(例如SomeInteface.FOO接口中的值)来避免此问题。

  • 恕我不能赞同。它仍然成为 API 的一部分。我仍然可以实现 SomeInterface。我仍然可以编写接受 SomeInterface 作为参数的公共方法。我们是否只是相信每个人都会遵守没有人实现 SomeInterface 的协议?这只会要求开发人员走捷径并降低代码质量。至少具有无参数构造函数的类对其意图更加清楚。它是一个没有行为、只有数据的类。接口无法传达这一点,因为它们一开始就没有行为。不清楚接口只是一个常量桶。 (2认同)