2

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

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

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

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

4

4 回答 4

3

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

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

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

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

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

于 2014-11-21T13:17:44.663 回答
1

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

于 2014-11-21T13:22:17.337 回答
1

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

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

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

于 2014-11-21T13:23:58.907 回答
0

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

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

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

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

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

于 2014-11-21T13:36:42.387 回答