我对我的程序设计有疑问。我有一个存储公共常量的类A,以便我可以在另一个类中使用这些常量。
public static final String error_code1 = "Fatal Error";
public static final String error_code2 = "XXXX";
...
...
在Composition与Interface之间,我不知道哪一个更合适。从我的想法,因为我只需要在我的程序中进行价值比较的常数,所以我认为组合就足够了(低耦合)。
但是,你们可以从软件设计的角度给我一些建议/论据吗? (凝聚力,耦合,维护困难等)
答案 0 :(得分: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来获取常量。
答案 1 :(得分:1)
将接口添加到接口被视为反模式,因为接口的主要目的是定义行为合同。使用枚举或直接访问它们,因为它们是公开的。
答案 2 :(得分:1)
我不会使用interface来存储常量,因为将静态成员放入接口(并实现该接口)是一种不好的做法,甚至还有一个名称,常量接口反模式,参见[Effective Java] [1],第17项:
常量接口模式是接口使用不佳。类在内部使用一些常量是一个实现细节。实现常量接口会导致此实现细节泄漏到类的导出API中。类的用户实现一个常量接口并不重要。事实上,它甚至可能使他们感到困惑。更糟糕的是,它代表了一种承诺:如果在将来的版本中修改了类以便它不再需要使用常量,它仍然必须实现接口以确保二进制兼容性。如果非最终类实现了一个常量接口,那么它的所有子类的命名空间都会受到接口中常量的污染。
我个人会去枚举,如果需要,我甚至可以使用它来获取错误代码或添加相关的字段/方法。
答案 3 :(得分:0)
String / int / ...另一个类中的常量有一个问题:它们被复制到使用类'常量池,之后不存在对原始类的导入。如果您随后更改常量值,则不会强制重新编译using类。
解决方案是使用界面,并且"实施"那个界面;可能是丑陋的。 更好的是使用枚举。
对于开放式值域,不会使用枚举,而是使用面向对象的方法:
abstract class ParseError extends RuntimeException
class ExpressionExpectedError extends ParseError
class DigitsMayNotFollowLeadingZeroError extends ParseError
..
在javadoc中,可能会看到ParseError的所有子类。这里的类本身形成域值,实例化承载实际的上下文信息。那是更多的OOP。在对象上调用多个方法比在常量上调用多个方法要好。然而,枚举也可以与分类方法一起使用:boolean errorHandledBySkippingToNextExpr()
。