【面向对象设计基础】常量数据管理器

作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/

a)使用场景:在程序设计中,我们可以把所用要用到的常量设计为一个独立的类,使得对常量的管理有效清晰。

 

b)应用举例:

我们考虑一个顾客数据存储的应用场景,要用到三种类,Account, Address 和 CreditCard来代表用户数据信息。

image

image

image

 

我们设计了一个常量管理器对常量进行集中管理,UML如下:

image

public final class ConstantDataManager {
    public static final String ACCOUNT_DATA_FILE = "ACCOUNT.TXT";
    public static final int VALID_MIN_LNAME_LEN = 2;
    public static final String ADDRESS_DATA_FILE = "ADDRESS.TXT";
    public static final int VALID_ST_LEN = 2;
    public static final String VALID_ZIP_CHARS = "0123456789";
    public static final String DEFAULT_COUNTRY = "USA";
    public static final String CC_DATA_FILE = "CC.TXT";
    public static final String VALID_CC_CHARS = "0123456789";
    public static final String MASTER = "MASTER";
    public static final String VISA = "VISA";
    public static final String DISCOVER = "DISCOVER";

    private ConstantDataManager (){
       throw new AssertionError();
    }


}

定义这个黑体字的这个private构造函数意图在于,不让这个类实例化。而定义这个常量类时用到的final则说明这个类不要再被继承了。

 

c)注意:

不要把常量定义在interface中,虽然在interface中声明的字段在编译时都会自动加上static final,看着貌似很像常量的样子。之所以这么说是因为Java是动态语言,对一些字段的引用可以在运行时动态进行,我们有时利用这个特性只编译有改动的项目部分,而其余部分不变。但是常量有时候我们是需要调整的,比如,AGE_LIMIT可能就从16调整的18。这样只编译这个接口文件而不编译使用该接口的文件则可能会出现问题:

//file A.java
public interface A{
    int AGE_LIMIT = 16;
}
//file B.java
public class B{
    public static void main(String[] args){
        System.out.println("Age Limit is " + A.AGE_LIMIT);
    }
}编译A.java和B.java,运行B结果为Age Limit is 16,但是我们现在修改A.java 改为18,编译A,(不编译B),运行B,结果仍为Age Limit is 16。这就不是我们想看到的了,原因在于编译器已经将interface A中的AGE_LIMIT 内容编译进了class B中,而不是对interface A中的的引用。

同时这个也不符合interface应该专注于Service而不是Data这个设计宗旨。

作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/

原文地址:https://www.cnblogs.com/gnuhpc/p/2822390.html