1

我收到了一个工作代码(Java 1.7),它执行以下操作:将文件中的字符串数组(血液测试名称列表)加载到字符串数组成员中(使用 Properties 和 FileInputStream)。该文件可以更改字符串,但含义保持不变(例如:一个测试可以称为“abc”,而在另一个运行中它称为“zzz”)。我有一个枚举测试名称的枚举类。枚举字符串与输入的字符串不同(因为后者可以更改)。

文件 bloodtest.names 包含:

bloodTestNames=abc;def;123;

代码:

public enum BloodTestNames {
AAA,BBB,CCC;    
}

Properties props = new Properties();
FileInputStream fis = new FileInputStream("bloodtest.names");
props.load(fis);
String testName[]=props.getProperty("bloodTestNames").toString().split(";");

现在回答问题: 问题 1:当我知道测试名称时,我需要返回文件中设置的字符串(例如:返回值 BBB 的“def”)。这样做最好的是什么?

我想出的最好方法是:

return testName[BloodTestNames.BBB.ordinal()]

问题 2:如果 BBB 在编译时未知 - 我如何完成相同的目标?

三分: * 我是 C 的老手,但 Java 的新手。欢迎任何做和不做的事。假设我的 Java 知识为零。* 我不完全重构是这里需要的。*我可能忘记提及重要细节,请询问,我会感觉到缺失的空白

4

3 回答 3

1

使整个设置驱动:添加一个 statuc 方法来加载哪些字符串映射到哪些枚举的设置,并添加一个使用这些设置的工厂方法:

public enum BloodTestNames {
    AAA,BBB,CCC; 
    private static Map<String, BloodTestNames> map = new HashMap<String, BloodTestNames>();

    public static void addAlias(String alias, String name) {
        map.put(alias, valueOf(name));
    }

    public static BloodTestNames getByAluas(String alias) {
        if (map.containsKey(alias))
            return map.get(alias);
        // own name assumed to be mapped
        return valueOf(alias);
    }
}

BloodTestNames.addAlias()启动时,根据一些设置文件重复调用以加载映射。

当您读取保存的文件时,用于BloodTestNames.getByAlias()返回给定字符串值的枚举。


你最好用单数命名你的类,然后去掉“名称”,即BloodTest- 为每个枚举命名类(所有枚举都有一个“名称”,它是编码的实例名称)。

于 2013-06-18T21:38:22.153 回答
1

我首先假设您确实需要枚举常量来建模这个用例,因为您有某种特定的代码要为每种血液测试执行(否则,一组简单的字符串就足够了,而且更灵活,因为您不需要预先知道测试的数量或关心他们的名字)。


Q1:由于 Java 枚举不仅仅是一个值序列,因此您可以充分利用其面向对象的特性。

public enum BloodTest {
    AAA, BBB, CCC;

    private static String[] names;

    public static void setNames(String[] names) {
        if (BloodTest.names != null)
            throw new IllegalStateException("You can only set the names once");
        if (names.length != values().length)
            throw new IllegalArgumentException("Wrong number of names");
        BloodTest.names = names;
    }

    @Override
    public String toString() {
        return names[ordinal()];
    }
}

现在你需要做的就是通过调用来初始化你的枚举BloodTest.setNames(namesFromConfiguration),然后你可以通过调用它的标准toString()方法来获取每个常量的字符串表示:BloodTest.BBB.toString().

由于最初的假设是您对每种测试类型都有一些特定的逻辑,因此我建议逻辑(以及所需的属性)也将封装在枚举本身或枚举常量中;例如:

public enum BloodTest {
    AAA(10) {
        @Override
        public boolean isRequired(MedicalRecord medicalRecord) {
            return medicalRecord.includes("someDisease");
        }
    },
    BBB(15) {
        @Override
        public boolean isRequired(MedicalRecord medicalRecord) {
            return ! medicalRecord.hasTakenBloodTestsLately();
        }
    },
    CCC(20) { // ... also implements the abstract method and so on

    private final int threshold;

    private BloodTest(int threshold) {
        this.threshold = threshold;
    }

    public boolean hasPassed(int value) {
        return value <= threshold;
    }

    public abstract boolean isRequired(MedicalRecord medicalRecord);

    // ... same as above
}

现在,一旦您获得对 some 的引用BloodTest,您就可以通过调用相应的方法而不使用switching 并让逻辑在客户端代码周围传播来检查该特定测试是否通过:

BloodTest bloodTest = BloodTest.valueOf(someString); // someString can be "AAA", "BBB" or "CCC"
// no matter which constant this is, you use it as an object and rely on polymorphism
if (bloodTest.hasPassed(someValue)) { // ... do something

Q2:您的问题 2 是我对您实际需要枚举的初步假设。如果您有可能需要动态处理您还不知道的血液测试,那么您不能使用枚举。

换句话说,如果您的代码没有任何switchif/else if块来处理每次血液测试,那么枚举对于您的用例来说是一个非常糟糕的选择。

但是,如果确实如此,那么我建议重构代码以将逻辑包含在枚举本身中,就像上面的示例一样,而不是switch/if块;此外,如果你switch有一个default案例(或者你if有一个最终else块),这仍然可以在枚举本身中建模,例如通过添加一个DEFAULT常量作为后备。

于 2013-06-20T01:10:03.217 回答
0

我的枚举类之一的简短摘录:

public enum TypesStructurelsE {
    SOURCE("SRC"),
    COLONNE("COL");

    private String code;

    TypesStructurelsE(final String code1) {
        code = code1;
    }


    /** @return String */
    public String getCode() {
        return code;
    }

    public void setCode(final String newCode) {
        code = newCode;
    }
}

. . 在其他班级

if(TypesStructurelsE.SOURCE.getCode().equal(testName[i])){ // can be "COL" or "SRC" 
//
;
}

...改变价值:

TypesStructurelsE.SOURCE.setCode("SOURCE_NEW");

因此,如果您的属性文件发生更改,您只需使用新符号 (SRC --> SOURCE) 进行编译

于 2013-06-18T14:02:44.600 回答