【问题标题】:Java, interface or composition for constants classJava、接口或常量类的组合
【发布时间】:2015-01-19 15:43:14
【问题描述】:

我对我的程序设计有疑问。我有一个存储公共常量的 A 类,以便我可以在另一个类中使用这些常量。

public static final String error_code1 = "Fatal Error";
public static final String error_code2 = "XXXX";
...
...

Composition vs Interface,我不知道哪个更合适。从我的想法来看,因为我只需要在我的程序中进行值比较的常量,所以我认为组合就足够了(低耦合)。

但是你们能从软件设计的角度给我一些建议/论据吗? (内聚、耦合、维护困难等)

【问题讨论】:

  • 这个可以用 Enums 完美解决。
  • 最好使用枚举,否则使用接口。

标签: java class-constants


【解决方案1】:

首先,我建议您在这种情况下使用枚举。

public enum ErrorCode {
    FATAL_ERROR("Fatal Error"),
    X_ERROR("XXXX");

    public final String msg;
    private ErrorCode(String msg) {
        this.msg = msg;
    }
}

如果由于某种原因这不适合您,我会使用带有私有(未使用)构造函数的 final 实用程序类。

无论如何,由于字段是静态的和最终的,我不会考虑引用 A 或实现 A 来获取常量。

【讨论】:

  • 接口不会比具有私有构造函数的最终类更好吗?
  • 这类字段是实现细节而不是类的契约。仅仅因为它“方便”并不意味着它是一个好主意。在不知不觉中,有人实现接口来简化对常量的访问。 2 天后,没有意识到字段是静态的,开始传递 ErrorConstants 类型的对象。
【解决方案2】:

向接口添加常量被认为是一种反模式,因为接口的主要目的是定义行为契约。使用枚举或直接访问它们,因为它们是公开的。

【讨论】:

  • 是的,我认为接口不应该用于常量,因为它违背了拥有接口的目的
【解决方案3】:

我不会使用接口来存储常量,因为将静态成员放入接口(并实现该接口)是一种不好的做法,甚至还有一个名称,Constant接口反模式,参见 [Effective Java][1],第 17 条:

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

我会亲自使用枚举,如果需要,我什至可以使用它来生成错误代码或添加相关字段/方法。

【讨论】:

    【解决方案4】:

    String/int/... 另一个类中的常量有一个问题:它们被复制到使用类的常量池中,然后不存在对原始类的导入。如果您随后更改常量的值,则不会强制重新编译 using 类。

    解决方案是使用接口,并“实现”该接口;也许丑陋。 更好的是使用枚举。

    对于开放式值域,我们不会使用枚举,而是使用面向对象的方法:

    abstract class ParseError extends RuntimeException
    class ExpressionExpectedError extends ParseError
    class DigitsMayNotFollowLeadingZeroError extends ParseError
    ..
    

    在 javadoc 中可能会看到 ParseError 的所有子类。在这里,类本身形成域值,并且实例化承载实际的上下文信息。那是更多的OOP。在一个对象上调用多个方法比对常量进行多个开关要好。然而,枚举也可以与分类方法一起使用:boolean errorHandledBySkippingToNextExpr()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 2014-06-01
      • 2019-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多