通过访问器方法封装 java.util.Properties 访问被认为是不好的做法?

Encapsulating java.util.Properties access through accessor methods considered bad practice?

我正在为我正在进行的项目使用 java.util.Properties。我有一个 class 管理一个带有 Properties 实例的 .properties 文件,名为 PropertiesManager。此 class 管理从光盘加载和保存 .properties 文件。

现在因为我想确保一个人只能访问有效的属性并且当 属性 不在文件中时使用默认值,我为每个 属性 添加了 getter 和 setter文件。

问题在于 class PropertiesManager 非常大。仅 getter 和 setter(comments/blank 行)就有 300 行代码。因此,即使我将 loading/saving 转移到另一个 class(继承等)中,它仍然很大。

这不是实际的代码,但它给了你一个想法:

import java.util.Properties;

public class PropertiesManager {
    private Properties properties;

    public PropertiesManager() {
        // constructor
    }

    private void save() {
        // save in .properties file
    }

    private void load() {
        // load from .properties file
    }

    public String getPropertyName1() {
        return properties.getProperty("PropertyName1", "Property1DefaultValue");
    }

    // 28 more getters here

    public String getPropertyName30() {
        return properties.getProperty("PropertyName30", "Property30DefaultValue");
    }

    public void setPropertyName1(String value) {
        properties.setProperty("PropertyName1", value);
    }

    // 28 more more setters here

    public void setPropertyName30(String value) {
        properties.setProperty("PropertyName30", value);
    }
}

像这样封装您对 Properties 实例的访问是否被认为是不好的做法?我应该直接使用 Properties 实例而不是使用访问器方法吗?还有其他解决方案吗?

我只想将其更改为使用枚举的单个 getter/setter:

public class PropertiesManager {
    ...
    public String getProperty(EnumProp enumProp) {
        return properties.getProperty(enumProp.getKey(), enumProp.getDefaultValue());
    }

    public void setProperty(EnumProp enumProp, String value) {
        properties.setProperty(enumProp.getKey(), value);
    }
}

有了这个枚举:

public enum EnumProp {
    PROP_1("key", "defaultValue"),
    ...

    EnumProp(String key, String defaultValue){
        this.key = key;
        this.defaultValue = defaultValue;
    }
}

Is it considered bad practice to encapsulate your access to the Properties instance like this? Should I just use the Properties instance directly instead of using accessor methods? Is there another solution?

解决起来比较麻烦

我认为如果使用 属性 文件包含键的所有默认值,如果未提供默认值,则应使用默认值,这样会更易于维护和阅读。

此解决方案的优点是您无需修改​​代码即可更改默认值。您只需更改默认的 属性 文件,该文件可能位于应用程序的包装之外。

在您的 PropertiesManager 包装器 class 中,提供一个类似于 Properties class 的 getProperty() 方法的 public String getProperty(String key) 方法,如果该值未在有效属性文件中提供,使用默认属性文件 return 默认值(如果存在)。

public String getProperty(String key) {
     String value= properties.getProperty(key);
     if (StringUtils.isEmpty(value)){
           value= propertiesDefault.getProperty(key);
     }
    return value;
}

对于 setProperty() 方法,您可以依赖相同的逻辑。

封装 Properties 实例 有意义。您 想要 公开的是委托给底层 Properties 实例的实例。我建议您枚举所有支持的属性以减少 PropertiesManager:

的 public 接口
public class PropertiesManager {
    public enum Property {
        SOMETHING("PropertyName1", "PropertyName1DefaultValue"),
        ANOTHER("PropertyNameX", "PropertyNameXDefaultValue"),
        …;

        public final String key;
        public final String defaultValue;

        Property(String key, String defaultValue) {
            this.key = key;
            this.defaultValue = defaultValue;
        }
    }

    private Properties properties;

    public PropertiesManager() {
    }

    private void save() {
        // save in .properties file
    }

    private void load() {
        // load from .properties file
    }

    public String get(Property property) {
        return properties.getProperty(property.key, property.defaultValue);
    }

    public void set(Property property, String value) {
        properties.setProperty(property.key, value);
    }
}

现在您可以简单地调用 propertyManager.get(SOMETHING) 等等。