【问题标题】:How to handle large number of configuration parameters across a program conceptually? [closed]如何从概念上处理跨程序的大量配置参数? [关闭]
【发布时间】:2015-09-28 14:43:16
【问题描述】:

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

哪种方法更好:

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

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

【问题讨论】:

    标签: parameters configuration configuration-files


    【解决方案1】:

    我建议您执行以下步骤。

    首先,使用支持多个部分/范围概念的配置文件语法,最好是可嵌套范围。例如,在我所说的意义上,XML 元素是一个可嵌套的范围,而“.ini”文件提供了不可嵌套的部分。 Java 属性文件不提供对作用域的直接支持,但您可以通过使用语法x.y.z 来模拟这种支持,在作用域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");
    }
    

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

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

    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 Config4* 的应用程序中使用了上述方法,并且对我来说效果很好。如果您使用的语言内置了对反射的支持(例如 Java),那么另一种方法是使用依赖注入框架。如果您不知道那是什么,请在 Internet 上搜索“依赖注入”、“控制反转”或“Spring 框架”。

    【讨论】:

    • 感谢您的详尽回答!多个顶级范围的想法很简洁,我将在我的设置中采用它(Python,顺便说一句。)。
    猜你喜欢
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    • 2022-09-29
    相关资源
    最近更新 更多