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

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

问题描述

假设一个软件系统,你有100个参数,每个都是敏感的改变(在我的情况下,这是一个reasearch系统的机器学习)。明显的解决方案是将所有参数存储在配置文件中,以便系统易于处理和查看。



Whis方法更好:




  • a)在程序的入口点加载配置文件,并通过代码中的每个方法传递一组大量的配置变量

  • b)在程序的入口点加载配置文件,并通过代码中的每个方法传递相关的配置变量集合

  • c)加载配置



I 可以提供特定实现的建议或示例。目前我正在尝试嵌套的配置变量,每个嵌套对象在代码中存储不同模块的配置。

解决方案

I建议您执行以下步骤。



首先,使用支持多个节/范围(最好是可嵌套范围)的概念的配置文件语法。例如,在我所说的意义上,XML元素是一个可嵌套的范围,而.ini文件提供了不可嵌套的部分。 Java属性文件不提供对范围的直接支持,但您可以使用语法 xyz 来表示变量 z ,范围 y ,其又嵌套在范围 x 中。 Config4 * (我开发的)为嵌套范围提供了直接支持。



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

  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);
}



在上面的伪代码中,我使用 前缀表示一个实例变量,我假设配置类有一个 lookup()操作,例如 cfg.lookup(foo.bar.abc)将返回 abc



第三, > main()函数可以写成如下伪代码:

  main (...){
String configFileName = ...; //从命令行参数获取
String scope = ...; //从命令行参数获取
配置cfg = parseConfigurationFile(configFileName);
Foo foo = new Foo(cfg,scope +.foo);
... //创建其他配置的对象
doRealWork(foo,...);最后,你的应用程序的命令行参数应该指定:(1)在应用程序中使用的命令行参数应该包含以下命令:
}


$ b <配置文件的名称,以及(2)保存运行应用程序的配置变量的顶级作用域(在配置文件中)。例如,让我们假设 example.cfg 的结构如下:

  instance1 {
foo {
x =a value;
y =另一个值;
z =另一个值;
bar {
...
}
}
...其他对象的#配置
}

instance2 {
foo {
x =...;
y =...
z =...
bar {
...
}
}
...其他对象的#配置
}

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



以上建议提供了以下好处:




  • 您的应用程序可以创建多个 Foo 对象,每个对象都可以配置不同,只需向每个对象的构造函数传递一个不同的 scope

  • 用户可以灵活地在单个配置文件中存储多组配置变量,如果他们想要的话。例如,用户可能具有不同的配置变量集,用于:(1)不同的单元测试; (2)开发,UAT和生产环境; (3)复制服务器应用程序的多个实例。

  • 随着时间的推移,您可以编写一个遵循上述设计原则的可配置类库。



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


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.

Whis approach is better:

  • a) load the config file at the entry point of the program and pass down a big collection of config variables through each method in the code
  • b) load the config file at the entry point of the program and pass down the relevant collection of config variables through each method in the code
  • c) load the config variables directly where they are needed
  • d) load the config and make it global

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.

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.

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");
}

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.

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, ...);
}

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
}

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

The above advice provides the following benefits:

  • 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.

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天全站免登陆