【发布时间】:2019-12-02 14:15:47
【问题描述】:
在泛型库中处理编译时和运行时选项的正确方法是什么?对于大型软件来说,什么是好的做法,其中有太多的选项供用户使用?
假设任务是编写一个大型库来同时对多个数据集执行计算。有许多方法可以执行这些计算,并且库必须是高度可配置的。通常,存在与如何作为一个整体执行计算相关的选项。然后,每个数据集都有自己的一组计算选项。最后,每个计算都有一些调整参数,这些参数也必须设置。
库本身是通用的,但使用该库的每个应用程序都将使用特定类型的数据集,调整参数将具有特定值。由于它们在应用程序的整个生命周期中都不会改变,因此我在应用程序编译时让它们知道。我在库中实现这些调整参数的方式是通过Traits 类,其中包含调整参数为static const 元素。校准它们的最终值是应用程序开发的一部分。
数据集当然会根据用户向应用程序提供的内容而变化,因此还必须提供许多 runtime 选项(具有智能默认值)。校准它们的默认值也是应用程序开发的一部分。我会将这些选项实现为包含这些选项的Config 类,并且可以在应用程序启动时进行更改(例如解析配置文本文件)。它被传递给库中许多类的构造函数。然后每个类调用Config::get_x 来获取他们的特定选项x。
我不太喜欢这种设计的一点是,Traits 和 Config 类都破坏了封装。一些选项与库的某些部分有关。然而,大多数时候,他们没有。让它们突然挨在一起让我很恼火,因为它们会影响代码中不同的东西,这些东西通常位于不同的抽象层中。
我正在考虑的一个解决方案是对这些不同的部分使用多个公共继承。需要知道选项的类然后转换Config 对象或调用相关的Trait 父对象来访问它。此外,将Config 传递给每个需要它(或其成员需要它)的类是非常不雅的。也许Config 应该是单身人士?
【问题讨论】:
标签: c++ c++11 runtime options compile-time