特色切换意大利面可以使用哪种设计模式?

Kra*_*mer 5 configuration design-patterns featuretoggle

我工作的公司已经深入研究了功能切换配置键,这些键可以根据特定条件打开/关闭特定行为。马丁·福勒(Martin Fowler)实际上将它们称为业务切换(http://martinfowler.com/bliki/FeatureToggle.html)。

我们有许多客户都在使用相同的服务,但是每个客户都希望行为有所不同。更糟糕的是,许多人希望其用户的某些子组看到不同的行为。因此,我们使用业务切换。切换开关已成为具有if / else逻辑的意大利面球,偶尔会有意外的交互。

是否有任何设计模式可用于管理此类情况?

干杯!

Bit*_*ler 2

我觉得用一个小例子更容易回答这个问题:

示例问题:您有一个组件根据某些输入进行一些计算。根据客户的不同,以下情况往往会发生变化:

  • 输入数据的来源/格式
  • 输入数据的预处理
  • 根据客户用例计算某些输出的三种不同方法 [A..C]。
  • 计算结果的输出格式。

所以工作流程可能看起来有点像这样:

预处理 -> 使用 [A..C] 风味进行计算 -> 格式化输出 -> 完成。

我会考虑在没有一堆配置意大利面的情况下处理这个问题的设计是:

  1. 为每个处理步骤分类一个行为类型。在预处理步骤的示例中,这可能类似于 IInputShaper,负责将特定类型的输入数据转换为内部格式并进行一些预处理。可能这可以再次拆分:IInputFitter、IPreprocess。对于工作流程中的其他步骤,请执行相应操作。这为您留下了多种行为类型的契约(这也有利于理解您的问题领域。您现在可以轻松地看到自由度实际上来自哪里,系统有多少种不同的行为,并且您可以保留核心实现干净。您还可以测试核心代码库,可以记录每个行为契约的要求,并且可以以单元测试方式测试行为实现,而不是“体内” - 混乱地融入核心代码库。
  2. 根据步骤 1 中定义的契约实现每个行为。在行为实现中接受一些重复的代码,而不是过度设计并试图找出这些行为之间的共性。把事情简单化。并对他们每个人进行测试。

结果:具有 0 个配置选项的行为实现集合和具有 0 个配置选项的核心代码库。最后一步是为客户项目选择行为实现,如果有特殊的情况,可能会编写一个新的实现。

如果你做得对,你将永远幸福地生活,而无需改变合同和核心系统。如果您错过了一点完美的设计,您将需要进行几次迭代,直到找到最佳的合约接口设计,从而使您的核心代码库变得稳定。

通过这种方法,您还可以更轻松地估算工作量并为新客户编写报价单。如果您已经拥有所有行为实现或者是否需要编写一些新的行为实现,您可以简单地在报价阶段进行检查。如果您首先记录编写它们需要多长时间,您甚至可以很好地猜测所需的工时。