配置类/结构:图案还是反图案?备择方案?


10

如果将新的配置选项添加到程序,则在将选项带到需要对其执行操作的位置时,它通常会产生大量涟漪效应。我知道有三种基本的处理方法:

  1. 将所有配置设置传递给程序中明确需要它们作为原语的部分。这是最明确的方式,也是最能使事物解耦的方式。缺点是这既冗长又脆弱。

  2. 将最常用的配置设置设为全局/静态。这是最简单的方法,但是会引入一定距离的操作,阻碍了可测试性,并假定该配置确实是全局的(您在任何给定时间只需要一个配置)。

  3. 创建一个包含整个程序或程序中每个主要问题的所有配置选项的配置类/结构,然后将其显式传递。它不如(1)明确,但比(2)更明确。如果只想更改一个函数调用的设置,则可以克隆config对象并更改该值。这在测试和实践中都是有用的。但是,您仍然可能最终将大量信息传递给它不需要的功能,并且更改config类/结构中的值仍会导致一定距离的操作。

您会考虑(3)模式还是反模式?如果是反模式,您该怎么办?


关于3的一种变化-具有多个配置类,将适当的一个传递给需要的地方?
奥德

@Oded:我想强调一下这种可能性。编辑。
dsimcha 2011年

Answers:


4

最好的解决办法是进行多次配置界面,并根据需要实现它们。这既限制了可访问性,又使内容保持本地化。但是,仅在单个类中放弃所有配置并继续处理具有更多引人注目的问题,就值得付出太多的努力。这是配置,而不是UtterlyCrucialAlwaysChangingClass,它几乎保持不变。只要您不将其全部设置为全局且实现是一致的,我就不必担心。


4
+1表示某种东西在理论上不是理想的设计,但在考虑到简单性和更改的可能性(或缺少更改)时,在实践中可能仍然是好的。
dsimcha 2011年

我只抛出了四个参数,并用Settings类代替了它。感觉像是对的事情。
马丁·乌丁2014年

我不明白您在主张3个选择中的哪个。您能指定一下吗?
DBedrenko

1

我更喜欢您的选项1,因为去耦可以简化测试,并且对象所依赖的配置设置是明确的。如果对象需要配置设置,则可以通过构造函数参数或setter方法将其显式提供给该对象。通过使用依赖项注入框架将那些配置设置注入到对象中来减少冗长。


您自相矛盾:您说使用选项1,然后说“通过使用依赖项注入框架将这些配置设置注入对象来减少冗长”。这是选项3:构造函数注入。
DBedrenko 2015年

0

想象一下,如果您的配置文件是用XML编写的。然后,您可以仅将此XML片段传递给每个组件,以便它们获取其配置数据。

如果使用的是.NET,则可以使用DataContracts创建类,可以使用XmlSerialiser从配置Xml创建对象层次结构,并将这些对象作为配置传递。

然后,这将向您介绍下一个问题。您的配置数据包含三个不同部分。组织代码库以充当此特定产品的结构化应用程序配置。站点配置设置,其中包含特定于安装的设置以及用户首选项/设置数据,这些数据随系统上的每个用户而有所不同。

知道哪一部分是哪个,并将这些数据设置分开,将使安装更新变得更加简单(不会丢失客户设置)


0

我可以将选项3中的类设为静态。所以代替

//create SomeCl
Foo f = new Foo();
f.setConfigInst(cfg);
...
...
//Inside Foo
public void setConfig(MyAppConfig c) { localCfg = c; }
...
//somewhere else:
x = localCfg.getConfigForX();

您可以拥有:

//Inside Foo
x = MyAppConfig.getConfigForX();

让加载/保存配置数据的详细信息发生在MyAppConfig类内部。当然,您可能会有更复杂的变化,例如出于不同目的的不同类。

其中,这种做法将是一个问题的唯一情况是,如果你需要工作在不同配置的多个实例某种原因,在同一时间,虽然我还没有碰到过这样的情况。


1
在某些测试框架中运行单元测试时,这几乎会发生什么。但是,即使没有显式并行的单元测试,依赖全局状态的单元测试对象的工作也会很痛苦。
彼得Török

0

我正在一个项目中,我们正在使用“ 3层(接口,业务逻辑,数据访问)”方法。该应用程序可以是多用户Web服务器或客户端服务器。

我们使用3种不同的配置,第一种特定于PC,以适应用户的工作需求。第二个特定于当前用户,第三个全局配置适用于所有用户和客户端应用程序。

每个配置在应用程序的每个实例中都由一个对象表示。

这种方法可能对您的项目有帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.