0

我们正在与多个开发人员合作一个项目,目前从配置文件中检索值有点“狂野的西部”:

  • 每个人都使用一些字符串从 Config 对象中检索一个值
  • 这些键分布在多个类和包中
  • 有时甚至没有声明为常量
  • 键的命名不一致,配置文件 (.properties) 看起来很乱

我想解决这个问题并强制每个人明确定义他们的配置键。理想情况下在一个地方简化配置键的实际外观。

我正在考虑使用 Enum 作为键并将我的检索方法变成:

getConfigValue(String key)

变成类似的东西

getConfigValue(ConfigKey)

注意:我正在使用这种方法,因为 Preferences API 对我来说似乎有点矫枉过正,而且我实际上希望将配置放在一个简单的文件中。

这种方法有什么缺点?

4

3 回答 3

1

首先,FWIW,我认为这是个好主意。但是您确实特别询问了“缺点”是什么,所以:

最大的“缺点”是它将任何需要使用配置数据的ConfigKey类与该类联系起来。添加一个配置键用于向您正在处理的代码添加一个字符串;现在这意味着添加到enum 正在处理的代码中。这是(略微)更多的工作。

否则,您可能不会显着增加相互依赖性,因为我假设getConfigValue属于其中的类是您定义enum.

于 2012-05-18T13:04:15.557 回答
0

合并的另一个缺点是,如果您在同一代码库的不同部分有多个项目。当你开发时,你必须处理交付依赖,这可能是一个 PITA。

假设项目 A 和项目 B 计划按该顺序发布。在第 9 个小时突然政治力量发生变化,您必须在 A 之前交付 B。您是否重新打包配置来处理它?您的 QA 周期是否可以处理重新包装,或者是否会强制重置其时间线。

典型的发布问题,但只是您必须管理的另一件事。

于 2012-05-18T13:58:51.767 回答
0

从您的问题来看,很明显您打算为原始 Java Properties API 编写一个包装类,目的是让您的包装类提供更好的 API。我认为这是一个很好的方法,但我想提出一些我认为会改进你的包装 API 的东西。

我建议的第一个改进是检索配置值的操作应该采用两个参数而不是一个参数,并按以下伪代码所示实现:

class Configuration {
    public String getString(String namespace, String localName) {
        return properties.getProperty(namespace + "." + localName);
    }
}

然后,您可以鼓励每个开发人员定义一个字符串常量值来表示他们正在开发的任何类/模块/组件的命名空间。只要每个开发人员(以某种方式)为其命名空间选择不同的字符串常量,您就可以避免意外的名称冲突并促进一些有组织的属性名称集合。

我建议的第二个改进是你的包装类应该提供对属性值的类型安全访问。例如,提供,getString()但也提供名称为getInt()、和的方法。变体应将属性值作为字符串检索,尝试将其解析为适当的类型,如果失败则抛出描述性错误消息。该方法应将属性值作为字符串检索,然后根据使用逗号作为分隔符将其拆分为字符串列表。这样做将为开发人员提供一种一致的方式来获取列表值。getBoolean()getDouble()getStringList()int/boolean/doublegetStringList()

我建议的第三个改进是你的包装类应该提供一些额外的方法,例如:

int getDurationMilliseconds(String namespace, String localName);
int getDurationSeconds(String namespace, String localName);
int getMemorySizeBytes(String namespace, String localName);
int getMemorySizeKB(String namespace, String localName);
int getMemorySizeMB(String namespace, String localName);

以下是其预期用途的一些示例:

cacheSize = cfg.getMemorySizeBytes(MY_NAMSPACE, "cache_size");
timeout = cfg.getDurationMilliseconds(MY_NAMSPACE, "cache_timeout");

getMemorySizeBytes()方法应将字符串值(例如"2048 bytes"或)"32MB"转换为适当的字节数,并getMemorySizeKB()执行类似的操作,但返回以 KB 而非字节为单位的指定大小。同样,这些getDuration<units>()方法应该能够处理字符串值,例如,"500 milliseconds"和(转换为 , 比如说)。"2.5 minutes""3 hours""infinite"-1

有些人可能认为上述建议与提出的问题无关。实际上,他们确实如此,但以一种偷偷摸摸的方式。上述建议将产生一个配置 API,开发人员会发现它比“原始”Java 属性 API 更容易使用。他们将使用它来获得易于使用的好处。但是使用 API 会产生副作用,迫使开发人员采用命名空间约定,这将有助于解决有兴趣解决的问题。

或者换个角度来看,问题中描述的方法的主要缺点是它提供了一种双赢的局面:你赢了(通过对开发人员强加一个属性命名约定),但开发人员输了,因为他们交换了熟悉的另一个 API 的 Java Properties API,它不为他们提供任何好处。相比之下,我提出的改进旨在提供双赢的局面。

于 2012-05-18T21:25:55.967 回答