如何从概念上处理程序中的大量配置参数? [英] How to handle large number of configuration parameters across a program conceptually?

查看:22
本文介绍了如何从概念上处理程序中的大量配置参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一个软件系统,其中您有大约 100 个参数,每个参数都可以更改(在我的情况下,这是一个用于机器学习的研究系统).显而易见的解决方案是将所有参数存储在一个配置文件中,以便系统易于处理和查看.

Imagine a software system where you have like 100 parameters, each of which is sensible to change (in my case this is a reasearch system for machine learning). The obvious solution is to store all parameters in a config file, so that the system is easy to handle and see through.

哪种方法更好:

  • a) 在程序入口点加载配置文件,并通过代码中的每个方法传递大量配置变量
  • b) 在程序入口点加载配置文件,并通过代码中的每个方法传递相关的配置变量集合
  • c) 在需要的地方直接加载配置变量
  • d) 加载配置并将其设为全局

我愿意接受特定实现的建议或示例.目前我正在试验嵌套配置变量,每个嵌套对象在代码中存储不同模块的配置.

I'm open for suggestions or examples of a particular implementation. At the moment I'm experimenting with nested config variables, each nested object storing config of different modules in the code.

推荐答案

我建议您执行以下步骤.

I recommend you do the following steps.

首先,使用支持多节/范围概念的配置文件语法,最好是可嵌套范围.例如,在我所说的意义上,一个 XML 元素是一个可嵌套的范围,而.ini"文件提供了不可嵌套的部分.Java 属性文件不提供对作用域的直接支持,但您可以通过使用语法 xyz 来表示在作用域 yz 来模拟这种支持code>,依次嵌套在作用域 x 中.Config4*(我开发的)为嵌套作用域提供直接支持.

First, use a configuration file syntax that supports the concept of multiple sections/scopes, and preferably nestable scopes. For example, an XML element is a nestable scope in the sense I am talking about, while a ".ini" file provides non-nestable sections. A Java properties file does not provide direct support for scopes, but you can emulate such support by using the syntax x.y.z to denote variable z, in scope y, which in turn is nested in scope x. Config4* (which I developed) provides direct support for nested scopes.

其次,编写一个可配置的Foo类的构造函数,如下伪代码所示:

Second, write the constructor of a configurable Foo class as shown in the following pseudocode:

Foo(Configuration cfg, String scope) {
    _x = cfg.lookup(scope + ".x");
    _y = cfg.lookup(scope + ".y");
    _z = cfg.lookup(scope + ".z");
    _bar = new Bar(cfg, scope + ".bar");
}

在上面的伪代码中,我使用_前缀来表示一个实例变量,并且我假设Configuration类有一个lookup() 使用范围名称的操作,例如 cfg.lookup("foo.bar.abc") 将返回 abc 变量在 foo.bar 作用域.

In the above pseudo code, I use the _ prefix to denote an instance variable, and I assume the Configuration class has a lookup() operation that takes a scoped name, for example, cfg.lookup("foo.bar.abc") will return the value of the abc variable in the foo.bar scope.

第三,你的应用程序的main()函数可以写成如下伪代码:

Third, the main() function of your application can be written as shown in the following pseudocode:

main(...) {
    String configFileName = ...; // obtain from command-line argument
    String scope          = ...; // obtain from command-line argument
    Configuration cfg     = parseConfigurationFile(configFileName);
    Foo foo               = new Foo(cfg, scope + ".foo");
    ... // create other configured objects
    doRealWork(foo, ...);
}

最后,应用程序的命令行参数应指定:(1) 配置文件的名称,以及 (2) 包含用于运行应用程序的配置变量的顶级范围(在配置文件中).例如,假设 example.cfg 的结构如下:

Finally, command-line arguments to your application should specify: (1) the name of a configuration file, and (2) a top-level scope (within the configuration file) that holds configuration variables for running the application. For example, let's assume example.cfg is structured as follows:

instance1 {
    foo {
        x = "a value";
        y = "another value";
        z = "yet another value";
        bar {
           ...
        }
    }
    ... # configuration for other objects
}

instance2 {
    foo {
        x = "...";
        y = "...";
        z = "...";
        bar {
           ...
        }
    }
    ... # configuration for other objects
}

您可以将应用程序作为 myApp.exe -cfg example.cfg -scope instance1 运行.

You might run your application as myApp.exe -cfg example.cfg -scope instance1.

上述建议具有以下好处:

The above advice provides the following benefits:

  • 您的应用程序可以创建多个 Foo 对象,每个对象都可以进行不同的配置,只需将不同的 scope 参数传递给每个对象的构造函数即可.
  • 用户可以根据需要灵活地将多组配置变量存储在单个配置文件中.例如,用户可能有不同的配置变量集: (1) 不同的单元测试;(2) 开发、UAT 和生产环境;(3) 复制的服务器应用程序的多个实例.
  • 随着时间的推移,您可以编写一个遵循上述设计原则的可配置类库.该可配置类库可以在多个应用程序中重复使用.
  • Your application can create multiple Foo objects, each of which can be configured differently, simply by passing a different scope parameter to the constructor of each object.
  • Users have the flexibility of being able to store multiple sets of configuration variables inside a single configuration file, if they want. For example, a user might have different sets of configuration variables for: (1) different unit tests; (2) development, UAT and production environments; (3) multiple instances of a replicated server application.
  • Over time, you can write a library of configurable classes that follow the above design principle. That library of configurable classes can be reused across multiple applications.

我已经在我编写的几个基于 C++ 和 Java Config4* 的应用程序中使用了上述方法,并且它对我来说效果很好.如果您使用的语言具有内置的反射支持(例如 Java),那么另一种方法是使用依赖注入框架.如果您不知道那是什么,那么请在互联网上搜索依赖注入"、控制反转"或Spring 框架".

I have used the above approach in several C++ and Java Config4*-based applications that I wrote, and it has worked well for me. If you are using a language that has built-in support for reflection (such as Java), then an alternative approach is to use a dependency injection framework. If you don't know what that is, then do an Internet search for "dependency injection", "inversion of control" or "Spring Framework".

这篇关于如何从概念上处理程序中的大量配置参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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