将 属性 文件值与数据库中的数据耦合是一种反模式吗?

Is coupling property file values with data in a database an anti-pattern?

我正在开发一个应用程序,其中在属性文件中定义了一些配置值,其值或有效范围在某种程度上取决于数据库中存储的数据。

出于某些原因,这似乎是错误的,但我正在努力为这个或任何可能表明这是不好的做法的已发表文章找到一个名称。有人可以建议吗?

2016 年 2 月 15 日,Whosebug 用户 "zerobandwidth" 表示根据从数据库数据派生的环境界限来验证配置设置是个坏主意。现在 post 有人说这是个坏主意。 o.~

但是,说真的,任何时候你试图根据外部 环境进行输入验证,特别是当这些标准的推导依赖于像连接这样脆弱的东西时网络或数据库,你会玩得很开心。

如果我们必须为这种模式发明一个名称以使其感觉更正式,"unreliable fundamental dependency" 怎么样?这似乎有一个适当的臭内涵,对吧? ^_^

你的痛苦有一个名字,它就是耦合。

属性 文件——我收集的是服务器配置的一部分或与应用程序捆绑在一起——与数据库耦合。数据库中的更改将波及到 属性 文件。

这不是最糟糕的耦合——地狱圈是Pathological/Content耦合——但它仍然是耦合。

我想到了一些反模式。最合适的可能是 softcoding(与 hardcoding 值相反)。避免硬编码值和 "magic numbers" 通常是一件好事,但如果走极端就不是这样了。来自 Wikipedia entry:

The term is generally used where softcoding becomes an anti-pattern. Abstracting too many values and features can introduce more complexity and maintenance issues than would be experienced with changing the code when required.

由于您要求发表文章,有关软编码的更多详细信息可以在 The Daily WTF 中找到,其中 Alex 将软编码定义为...

the practice of removing "things that should be in source code" from source code and placing them in some external resource.

根据您的描述,这些值应该存储(或者可能计算)在源代码中,或者也存储在存储它们所依赖的值的数据库中,不在外部 属性 文件中。所以是的,我同意这里确实有一点 "design smell"。

在较小程度上,您可以争辩说这是应用 Cargo cult programming 的情况。

Cargo cult programming can also refer to the results of applying a design pattern or coding style blindly without understanding the reasons behind that design principle.

与应用 Golden Hammer 不太一样,但原理上有些相似。

(不过,在使用这些定义呈现 "authors" 此类代码时要小心,因为大多数开发人员往往不喜欢在他们的设计中向他们指出反模式。)

这是我的观点,但是...让我们简单点。

代码应包含适用于 运行 每个 existing/used 属性.
中 "safe mode" 代码的默认值 或者它可以作为 .properties 文件从本地资源加载...

获得 属性 的一种方法是将其集中在安全且受控的地方:

ParamaterService.init(); //whatever it's need, can be injected for DB
Integer myImportantValue = ParameterService.getMyImportantValue();

public final class ParameterService {
     private static Integer MY_IMPORTANT_VALUE_DEFAULT = 10;

     public Integer getMyImportantValue() {
        Integer value = getFromDb("MY_IMPORTANT_VALUE");
        if (value != null) {
            return value;
        }
        return MY_IMPORTANT_VALUE_DEFAULT;
    }
}

你的 "locals" 属性包含不能来自外部源的配置(众所周知的例子是数据库连接信息)。

其他一切都来自任何外部数据库。
根据上下文(例如:国际公司的国家/地区),您可能有不同的数据库。
无需转身混音。
如果您需要 validate/assert 值的内容,它仍然是可能的,getMyImportantValue 背后的代码由您自行决定。