Parameters 如何在概念上处理程序中的大量配置参数?

Parameters 如何在概念上处理程序中的大量配置参数?,parameters,configuration,configuration-files,Parameters,Configuration,Configuration Files,设想一个软件系统,其中有100个参数,每个参数都可以更改(在我的例子中,这是一个机器学习的研究系统)。显而易见的解决方案是将所有参数存储在一个配置文件中,以便系统易于处理和看穿 Whis方法更好: a) 在程序的入口点加载配置文件,并通过代码中的每个方法传递一大组配置变量 b) 在程序的入口点加载配置文件,并通过代码中的每个方法传递相关的配置变量集合 c) 直接在需要的地方加载配置变量 d) 加载配置并使其成为全局配置 我愿意听取关于特定实现的建议或示例。目前我正在试验嵌套的配置变量,每个嵌

设想一个软件系统,其中有100个参数,每个参数都可以更改(在我的例子中,这是一个机器学习的研究系统)。显而易见的解决方案是将所有参数存储在一个配置文件中,以便系统易于处理和看穿

Whis方法更好:

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

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

我建议您执行以下步骤

首先,使用支持多节/作用域概念的配置文件语法,最好是可嵌套作用域。例如,在我所说的意义上,XML元素是可嵌套的作用域,而“.ini”文件提供不可嵌套的部分。Java属性文件不提供对作用域的直接支持,但您可以通过使用语法
x.y.z
在作用域
y
中表示变量
z
,来模拟这种支持,而变量
z
又嵌套在作用域
x
中。(我开发的)直接支持嵌套作用域

其次,编写可配置的
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");
}
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, ...);
}
在上面的伪代码中,我使用
前缀表示一个实例变量,并且我假设
配置
类有一个
lookup()
操作,该操作使用一个作用域名称,例如,
cfg.lookup(“foo.bar.abc”)
将返回
foo.bar
范围中的
abc
变量的值

第三,应用程序的
main()

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");
}
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
的结构如下:

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
运行

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

  • 您的应用程序可以创建多个
    Foo
    对象,每个对象都可以进行不同的配置,只需将不同的
    scope
    参数传递给每个对象的构造函数即可
  • 用户可以灵活地在一个配置文件中存储多组配置变量(如果需要)。例如,用户可能有不同的配置变量集:(1)不同的单元测试;(2) 开发、UAT和生产环境;(3) 复制服务器应用程序的多个实例
  • 随着时间的推移,您可以编写一个遵循上述设计原则的可配置类库。该可配置类库可以跨多个应用程序重用

我在上面写的几个C++和基于java配置的应用程序中使用了上述方法,它对我来说很有效。如果您使用的语言具有内置的反射支持(如Java),那么另一种方法是使用依赖注入框架。如果你不知道这是什么,那么在互联网上搜索“依赖注入”、“控制反转”或“Spring框架”。

谢谢你的详尽回答!多个顶级作用域的想法很好,我将在我的设置中采用它(Python,顺便说一句)。