将配置传递给与应用程序无关的模块的最佳方法是什么?

时间:2009-01-27 07:58:21

标签: delphi configuration-management

我正在开发一个由多个模块组成的应用程序,这些模块又将用于其他应用程序。这些模块中的每一个都需要一些配置选项,但不应该知道其他模块的选项,也不应该要求其他模块存在。某些设置在模块之间共享。

假设模块A需要设置x和y,模块B需要设置y和z。

设置存储在注册表中或一个或多个.ini文件中。

到目前为止,我已经考虑过以下方法:

  1. 拥有一个全球单位(“global.pas”) 包含在所有模块中 包含全局变量 设置。我不喜欢这种方法 非常因为它需要 所有申请都有这样一个单位 它必然会收集很多 没有任何内容的附加代码 做到最初的目的。所以 最终每个申请都会 有自己不兼容的全局 单元。
  2. 为每个模块提供包含该模块所需的所有设置的配置类。它们从应用程序中的某个中心点传递到模块中,该中心点还处理读取和写入某些永久形式(例如,使用JvAppStorage)。这需要模块之间的一些同步,因为一些选项将在它们之间共享,因此如果在一个模块中更改选项,则此更改必须以某种方式反映在另一个模块的配置中(不一定是实时的,而是下次模块已初始化)。
  3. 拥有一个通用配置类,该类传递给每个模块,并包含所有模块的设置作为属性。每个模块仅访问它知道的那些设置。这里的问题可能是名称冲突不会被注意到。另外,我不喜欢传递配置选项的想法,这对模块来说是不必要的。此外,每个应用程序将包含不同的模块子集,但最终将包含相同的配置类以及所有可能模块的选项。 (这与上面的全球单位方法没有太大差别。)
  4. 拥有传递给每个模块的通用配置类,如上所述。但是,模块不是拥有属性,而是通过名称访问它们的设置(在最简单的情况下,这可能是TCustomIniFile)。这样可以避免对所有应用程序中可用的所有模块进行设置,但会引入可能的类型兼容性问题,同样,名称冲突可能会成为一个问题(除非每个模块的名称前缀为其选项,但是它们不能再共享选项)。
  5. 我想每个编写模块化系统的人都面临这个问题,并发现他们后来遇到的一些解决方案,无论他们是否仍然喜欢它们。我也去过那里,好几次,我还在寻找金色的子弹。

    也许其他人已经找到了理想的解决方案?

    (这是Delphi 2007,以防万一。我已经在使用JCL / JVCL了。)

2 个答案:

答案 0 :(得分:3)

我可能会创建一个通用配置类,并让每个模块依赖于一个或几个单例的具体配置类。模块依赖于具有仅对该模块有意义的设置的配置类实例,并且可选地依赖于具有与多个模块相关的设置的一个或多个其他配置类实例。由于配置对象是单例,共享配置对象的模块会自动获得相同的设置。

您可以根据功能创建配置类,而不是根据模块用法创建配置类。模块使用的功能暗示了它将需要哪些配置对象。

添加到应用程序的每个模块都会将所有必需的配置类添加为依赖项,而不会添加其他配置类。单例配置对象将自己添加到应用程序启动时此类对象的列表(或注册表中)。应用程序本身不需要了解详细信息,只需从持久存储加载和保存设置就足够了。如果需要,OTOH可以使用相同的基础设施。

通常我会根据接口实现所有内容,并将持久性机制留在外面。因此,您稍后可以在INI文件,注册表甚至数据库中进行配置(这将为您提供实现配置更改历史记录的简单方法)。我发现自从我开始编写接口而不是类的层次结构时,我并没有把自己锁定在一种做事方式上。

答案 1 :(得分:0)

我曾经有过这样的应用程序(用C ++ Builder编写)。 我有一个基本模块(BaseClass.BPL),所有其他模块(如Payment.BPL)继承自。因此,您可以使用基类来读取公共参数并覆盖继承的模块以读取特定设置。

void PaymentForm::Readsettings()
{
   BaseClass::ReadSettings(); //to read common stuff
   IniFile->ReadString("Payment Module", "setting1,...); //read specific stuff
}

我在INI文件中保留了设置 - 更容易处理该注册表。为避免与类似名称发生冲突,每个模块在INI中使用了不同的部分。

[Common]
Datapath=...
Server=...

[MainModule]
setting1=..

[Payment module]
setting1=....
setting3=....