以可维护的方式管理应用程序配置的模式
Pattern for managing application configuration in a maintainable way
我正在寻找用于管理跨平台 C++ 应用程序中的应用程序配置的 DRY 模式。
理想情况下,我希望有一个明确的应用程序配置源,以最大程度地减少开发人员的维护负担。这可以存储为 txt,XML,JSON,YAML
这个文件有两个用途...
首先,它用于创建用户可以访问的配置文件。
其次,它将确定在用户决定删除全部或部分配置文件的情况下使用的默认值。
我探索过的选项...
让某种预处理器在编译时将配置文件编译到应用程序中。这似乎不可能。
创建一个工具来读取配置文件,并生成必要的代码以在默认情况下编译到应用程序中。这可行,但会增加构建过程的复杂性,我想避免这种情况。
创建两个配置文件,一个是用户可配置的,另一个包含隐藏的默认值。在应用程序启动时,默认文件被读取,然后用户文件被读取,通过覆盖默认值来应用用户设置。这并不理想,因为它依赖于隐藏文件来保护用户的默认值安全。
Config4Cpp provides direct support for what you want to do. For details, read the discussion in Chapter 3 of the Config4* Getting Started Guide 关于嵌入式配置(将默认值硬编码到应用程序可执行文件中)和 回退配置 (本质上,从中查找请求变量的值一个已解析的配置文件,如果这不起作用,则 "fallback" 在嵌入式配置中查找值。
如果您想将此方法与另一种配置文件语法(例如,json 或 XML)结合使用,则归结为以下步骤:
编写类似于 config2cpp
的命令行实用程序(在 Chapter 6 of the Config4* Getting Started Guide 中讨论,将配置文件(或实际上任何文本文件)转换为(单例)C++ class 包含配置文件内容的快照,并且可以通过 public 方法提供对该快照的访问。您将使用应用程序的其余部分编译生成的 C++ class , 因此应用程序中嵌入了 "default" 个配置变量。
对您喜欢的配置文件语法使用解析器,但要确保解析器可以解析外部文件或嵌入式配置文件。换句话说,您应该能够执行 cfg.parseFile("file.cfg")
或 cfg.parseString(EmbeddedConfigurationClass::getString())
.
编写您自己的 "wrapper" 配置 API class,其中 两个 已解析的配置对象作为实例变量。这些变量之一将是解析的外部配置文件,另一个变量将是解析的嵌入式配置数据。实现包装器 class 的 lookup()
方法,使其首先在解析的外部配置文件中查找指定的变量;如果失败,则该方法会在嵌入式配置数据中查找指定的变量。
仅此而已。 Config4* 为您提供了上述开箱即用的功能,但是,正如我在上面的步骤中所描述的,无论您喜欢什么配置文件语法,都应该很容易模拟类似的功能。
顺便说一下,如果您实现了这个功能,那么我建议您将外部配置文件设为可选。这样做意味着您的应用程序将能够开箱即用,而无需用户首先显式创建配置文件。在 Config4* 中,我称之为 zero configuration.
我正在寻找用于管理跨平台 C++ 应用程序中的应用程序配置的 DRY 模式。
理想情况下,我希望有一个明确的应用程序配置源,以最大程度地减少开发人员的维护负担。这可以存储为 txt,XML,JSON,YAML
这个文件有两个用途...
首先,它用于创建用户可以访问的配置文件。
其次,它将确定在用户决定删除全部或部分配置文件的情况下使用的默认值。
我探索过的选项...
让某种预处理器在编译时将配置文件编译到应用程序中。这似乎不可能。
创建一个工具来读取配置文件,并生成必要的代码以在默认情况下编译到应用程序中。这可行,但会增加构建过程的复杂性,我想避免这种情况。
创建两个配置文件,一个是用户可配置的,另一个包含隐藏的默认值。在应用程序启动时,默认文件被读取,然后用户文件被读取,通过覆盖默认值来应用用户设置。这并不理想,因为它依赖于隐藏文件来保护用户的默认值安全。
Config4Cpp provides direct support for what you want to do. For details, read the discussion in Chapter 3 of the Config4* Getting Started Guide 关于嵌入式配置(将默认值硬编码到应用程序可执行文件中)和 回退配置 (本质上,从中查找请求变量的值一个已解析的配置文件,如果这不起作用,则 "fallback" 在嵌入式配置中查找值。
如果您想将此方法与另一种配置文件语法(例如,json 或 XML)结合使用,则归结为以下步骤:
编写类似于
config2cpp
的命令行实用程序(在 Chapter 6 of the Config4* Getting Started Guide 中讨论,将配置文件(或实际上任何文本文件)转换为(单例)C++ class 包含配置文件内容的快照,并且可以通过 public 方法提供对该快照的访问。您将使用应用程序的其余部分编译生成的 C++ class , 因此应用程序中嵌入了 "default" 个配置变量。对您喜欢的配置文件语法使用解析器,但要确保解析器可以解析外部文件或嵌入式配置文件。换句话说,您应该能够执行
cfg.parseFile("file.cfg")
或cfg.parseString(EmbeddedConfigurationClass::getString())
.编写您自己的 "wrapper" 配置 API class,其中 两个 已解析的配置对象作为实例变量。这些变量之一将是解析的外部配置文件,另一个变量将是解析的嵌入式配置数据。实现包装器 class 的
lookup()
方法,使其首先在解析的外部配置文件中查找指定的变量;如果失败,则该方法会在嵌入式配置数据中查找指定的变量。
仅此而已。 Config4* 为您提供了上述开箱即用的功能,但是,正如我在上面的步骤中所描述的,无论您喜欢什么配置文件语法,都应该很容易模拟类似的功能。
顺便说一下,如果您实现了这个功能,那么我建议您将外部配置文件设为可选。这样做意味着您的应用程序将能够开箱即用,而无需用户首先显式创建配置文件。在 Config4* 中,我称之为 zero configuration.