枚举中的可配置值 [英] Configurable Values in Enum

查看:185
本文介绍了枚举中的可配置值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常在我的代码中使用这个设计来保持可配置的值。考虑这个代码:

  public enum Options {

REGEX_STRING(Some Regex),
REGEX_PATTERN(Pattern.compile(REGEX_STRING.getString()),false),
THREAD_COUNT(2),
OPTIONS_PATH(options.config,false),
DEBUG ,
ALWAYS_SAVE_OPTIONS(true),
THREAD_WAIT_MILLIS(1000);

对象值;
boolean saveValue = true;

private选项(对象值){
this.value = value;
}

private选项(对象值,布尔值saveValue){
this.value = value;
this.saveValue = saveValue;
}

public void setValue(Object value){
this.value = value;
}

public Object getValue(){
return value;
}

public String getString(){
return value.toString();
}

public boolean getBoolean(){
Boolean booleanValue =(value instanceof Boolean)? (Boolean)value:null;
if(value == null){
try {
booleanValue = Boolean.valueOf(value.toString());
}
catch(Throwable t){
}
}

//这里需要一个NullPointerException
return booleanValue.booleanValue ;
}

public int getInteger(){
Integer integerValue =(value instanceof Number)? ((Number)值).intValue():null;
if(integerValue == null){
try {
integerValue = Integer.valueOf(value.toString());
}
catch(Throwable t){
}
}
return integerValue.intValue();
}

public float getFloat(){
Float floatValue =(value instanceof Number)? ((Number)value).floatValue():null;
if(floatValue == null){
try {
floatValue = Float.valueOf(value.toString());
}
catch(Throwable t){
}
}
return floatValue.floatValue();
}

public static void saveToFile(String path)throws IOException {
FileWriter fw = new FileWriter(path);
属性properties = new属性();
for(选项选项:Options.values()){
if(option.saveValue){
property.setProperty(option.name(),option.getString());
}
}
if(DEBUG.getBoolean()){
properties.list(System.out);
}
properties.store(fw,null);
}

public static void loadFromFile(String path)throws IOException {
FileReader fr = new FileReader(path);
属性properties = new属性();
properties.load(fr);

if(DEBUG.getBoolean()){
properties.list(System.out);
}
对象值= null;
for(选项选项:Options.values()){
if(option.saveValue){
Class<?& clazz = option.value.getClass();
try {
if(String.class.equals(clazz)){
value = properties.getProperty(option.name());
}
else {
value = clazz.getConstructor(String.class).newInstance(properties.getProperty(option.name()));
}
}
catch(NoSuchMethodException ex){
Debug.log(ex);
}
catch(InstantiationException ex){
Debug.log(ex);
}
catch(IllegalAccessException ex){
Debug.log(ex);
}
catch(IllegalArgumentException ex){
Debug.log(ex);
}
catch(InvocationTargetException ex){
Debug.log(ex);
}

if(value!= null){
option.setValue(value);
}
}
}
}
}


$ b b

这样,我可以轻松地保存和检索文件中的值。问题是,我不想在任何地方重复这个代码。就像我们知道的,枚举不能扩展;所以我使用这里,我必须把所有这些方法。我只想声明这些值,如果它们应该被持久化。每次没有方法定义;任何想法?

解决方案

使用枚举来保存可配置的值看起来像一个完全错误的设计。枚举是单例,因此在任何给定时间只能有一个配置活动。



一个 EnumMap 喜欢你需要的。它在枚举外部,因此您可以根据需要实例化多个配置。

  import java.util。*; 
public class EnumMapExample {
static enum选项{
DEBUG,ALWAYS_SAVE,THREAD_COUNT;
}
public static void main(String [] args){
Map< Options,Object> normalConfig = new EnumMap< Options,Object>(Options.class);
normalConfig.put(Options.DEBUG,false);
normalConfig.put(Options.THREAD_COUNT,3);
System.out.println(normalConfig);
// prints{DEBUG = false,THREAD_COUNT = 3}

映射< Options,Object> debugConfig = new EnumMap< Options,Object>(Options.class);
debugConfig.put(Options.DEBUG,true);
debugConfig.put(Options.THREAD_COUNT,666);
System.out.println(debugConfig);
// prints{DEBUG = true,THREAD_COUNT = 666}
}
}



API连结




  • java.util.EnumMap

    < blockquote>

    用于枚举类型键的专用映射实现。枚举映射中的所有键都必须来自在创建映射时显式或隐式指定的单个枚举类型。枚举映射在内部表示为数组。这种表示非常紧凑和高效。




I often use this design in my code to maintain configurable values. Consider this code:

public enum Options {

    REGEX_STRING("Some Regex"),
    REGEX_PATTERN(Pattern.compile(REGEX_STRING.getString()), false),
    THREAD_COUNT(2),
    OPTIONS_PATH("options.config", false),
    DEBUG(true),
    ALWAYS_SAVE_OPTIONS(true),
    THREAD_WAIT_MILLIS(1000);

    Object value;
    boolean saveValue = true;

    private Options(Object value) {
        this.value = value;
    }

    private Options(Object value, boolean saveValue) {
        this.value = value;
        this.saveValue = saveValue;
    }

    public void setValue(Object value) {
        this.value = value;
    }

    public Object getValue() {
        return value;
    }

    public String getString() {
        return value.toString();
    }

    public boolean getBoolean() {
        Boolean booleanValue = (value instanceof Boolean) ? (Boolean) value : null;
        if (value == null) {
            try {
                booleanValue = Boolean.valueOf(value.toString());
            }
            catch (Throwable t) {
            }
        }

        // We want a NullPointerException here
        return booleanValue.booleanValue();
    }

    public int getInteger() {
        Integer integerValue = (value instanceof Number) ? ((Number) value).intValue() : null;
        if (integerValue == null) {
            try {
                integerValue = Integer.valueOf(value.toString());
            }
            catch (Throwable t) {
            }
        }
        return integerValue.intValue();
    }

    public float getFloat() {
        Float floatValue = (value instanceof Number) ? ((Number) value).floatValue() : null;
        if (floatValue == null) {
            try {
                floatValue = Float.valueOf(value.toString());
            }
            catch (Throwable t) {
            }
        }
        return floatValue.floatValue();
    }

    public static void saveToFile(String path) throws IOException {
        FileWriter fw = new FileWriter(path);
        Properties properties = new Properties();
        for (Options option : Options.values()) {
            if (option.saveValue) {
                properties.setProperty(option.name(), option.getString());
            }
        }
        if (DEBUG.getBoolean()) {
            properties.list(System.out);
        }
        properties.store(fw, null);
    }

    public static void loadFromFile(String path) throws IOException {
        FileReader fr = new FileReader(path);
        Properties properties = new Properties();
        properties.load(fr);

        if (DEBUG.getBoolean()) {
            properties.list(System.out);
        }
        Object value = null;
        for (Options option : Options.values()) {
            if (option.saveValue) {
                Class<?> clazz = option.value.getClass();
                try {
                    if (String.class.equals(clazz)) {
                        value = properties.getProperty(option.name());
                    }
                    else {
                        value = clazz.getConstructor(String.class).newInstance(properties.getProperty(option.name()));
                    }
                }
                catch (NoSuchMethodException ex) {
                    Debug.log(ex);
                }
                catch (InstantiationException ex) {
                    Debug.log(ex);
                }
                catch (IllegalAccessException ex) {
                    Debug.log(ex);
                }
                catch (IllegalArgumentException ex) {
                    Debug.log(ex);
                }
                catch (InvocationTargetException ex) {
                    Debug.log(ex);
                }

                if (value != null) {
                    option.setValue(value);
                }
            }
        }
    }
}

This way, I can save and retrieve values from files easily. The problem is that I don't want to repeat this code everywhere. Like as we know, enums can't be extended; so wherever I use this, I have to put all these methods there. I want only to declare the values and that if they should be persisted. No method definitions each time; any ideas?

解决方案

Using an enum to hold configurable values like this looks like an entirely wrong design. Enums are singletons, so effectively you can only have one configuration active at any given time.

An EnumMap sounds more like what you need. It's external to the enum, so you can instantiate as many configurations as you need.

import java.util.*;
public class EnumMapExample {
    static enum Options {
        DEBUG, ALWAYS_SAVE, THREAD_COUNT;
    }
    public static void main(String[] args) {
        Map<Options,Object> normalConfig = new EnumMap<Options,Object>(Options.class);
        normalConfig.put(Options.DEBUG, false);
        normalConfig.put(Options.THREAD_COUNT, 3);
        System.out.println(normalConfig);
        // prints "{DEBUG=false, THREAD_COUNT=3}"

        Map<Options,Object> debugConfig = new EnumMap<Options,Object>(Options.class);
        debugConfig.put(Options.DEBUG, true);
        debugConfig.put(Options.THREAD_COUNT, 666);
        System.out.println(debugConfig);
        // prints "{DEBUG=true, THREAD_COUNT=666}"  
    }
}

API links

  • java.util.EnumMap

    A specialized Map implementation for use with enum type keys. All of the keys in an enum map must come from a single enum type that is specified, explicitly or implicitly, when the map is created. Enum maps are represented internally as arrays. This representation is extremely compact and efficient.

这篇关于枚举中的可配置值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆