Configuration 我们是否应该让配置设置的含义过载?

Configuration 我们是否应该让配置设置的含义过载?,configuration,Configuration,设想一个名为“配置”的配置设置查找实例,如下所示: if(! string.IsNullOrEmpty(configuration["MySetting"]) { DoSomethingWithTheValue(configuration["MySetting"]); } 设置的含义被重载。它的意思是“打开或关闭此功能”和“这里有一个特定的值可以使用”。这些可分解为两种设置: if(configuration["UseMySetting"]) { DoSomethingWith

设想一个名为“配置”的配置设置查找实例,如下所示:

if(! string.IsNullOrEmpty(configuration["MySetting"])
{
    DoSomethingWithTheValue(configuration["MySetting"]);
}
设置的含义被重载。它的意思是“打开或关闭此功能”和“这里有一个特定的值可以使用”。这些可分解为两种设置:

if(configuration["UseMySetting"])
{
    DoSomethingWithTheValue(configuration["MySetting"]);
}
第二种方法似乎使配置更复杂,但更容易解析,并将这两种行为分开。第一个看起来简单得多,但不清楚我们选择什么作为默认的“关闭此选项”设置。“”实际上可能是MySetting的有效值


有一个通用的最佳实践规则吗?

我发现这个问题有点让人困惑,因为它涉及(1)解析和(2)使用配置设置,但代码示例仅针对后者。这种混乱意味着我的回答可能与你想问的问题无关。无论如何

我建议使用以下伪代码API说明的方法(后面有注释):

类配置
{
无效解析(字符串文件名);
存在布尔值(字符串名称);
字符串查找字符串(字符串名称);
字符串查找字符串(字符串名称、字符串默认值);
int lookupInt(字符串名称);
int lookupInt(字符串名称,int defaultValue);
float lookupFloat(字符串名称);
float lookupFloat(字符串名称,float defaultValue);
布尔lookupBoolean(字符串名称);
boolean lookupBoolean(字符串名称,布尔默认值);
…//其他类型的更多lookup()操作对
}
parse()
操作解析配置文件,并将解析后的数据以方便的格式存储在映射或哈希表中。(如果需要,
parse()
可以将解析委托给第三方库,例如,XML、Java属性、JSON、.ini文件或其他文件的解析器。)

解析完成后,应用程序可以调用其他操作来检索/使用配置设置

lookup()
操作检索指定名称的值并将其解析为指定类型(如果解析失败,则引发异常)。每个
lookup()
操作都有两个重载。如果指定的变量不存在,则具有一个参数的版本将引发异常。如果指定的变量不存在,则带有额外参数(表示默认值)的版本将返回该默认值

exists()
操作可用于测试配置文件中是否存在指定的名称

上面的伪代码API提供了两个好处。首先,它提供了对配置数据的类型安全访问(这在您的问题中不是一个明确的要求,但我认为它无论如何都很重要)。其次,它使您能够区分“变量未在配置中定义”和“变量已定义,但其值恰好为空字符串”


如果您已经承诺使用特定的配置语法,那么只需将上面的
configuration
类作为现有配置语法的解析器的薄包装器来实现。如果您还没有选择配置语法,如果您的项目是C++或java,那么您可能需要查看我的库,它提供了一个使用的伪代码类(有几个额外的铃声和哨子)的准备使用。这不是主观的——这是我们在我目前的工作环境中需要解决的问题。
class Configuration
{
    void parse(String fileName);
    boolean exists(String name);
    String  lookupString(String name);
    String  lookupString(String name, String defaultValue);
    int     lookupInt(String name);
    int     lookupInt(String name, int defaultValue);
    float   lookupFloat(String name);
    float   lookupFloat(String name, float defaultValue);
    boolean lookupBoolean(String name);
    boolean lookupBoolean(String name, boolean defaultValue);
    ... // more pairs of lookup<Type>() operations for other types
}