How to handle large number of configuration parameters across a program conceptually? [closed]

六眼飞鱼酱① 提交于 2019-11-28 14:17:16

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!