什么设计模式可以用于功能切换意大利面?

时间:2015-09-01 20:12:57

标签: design-patterns configuration featuretoggle

我所工作的公司已经脱离了深层次的功能切换配置键,根据特定条件打开/关闭特定行为。 Martin Fowler实际上将它们称为业务切换(http://martinfowler.com/bliki/FeatureToggle.html)。

我们有很多客户都使用相同的服务,但每个客户都想要稍微不同的行为。更糟糕的是,许多人希望其用户的某些子群看到不同的行为。因此,我们使用业务切换。切换已经成为if / else逻辑的意大利面球,偶尔会有意想不到的相互作用。

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

干杯!

2 个答案:

答案 0 :(得分:2)

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

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

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

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

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

我会考虑设计一个没有一堆配置意大利面条的设计:

  1. 为每个处理步骤分类一种行为类型。在预处理步骤的示例中,这可能类似于IInputShaper,负责将特定类型的输入数据转换为内部格式并进行一些预处理。可能会再次分裂:IInputFitter,IPreprocess。对于工作流程中的其他步骤,请执行相应操作。这使您可以获得许多行为类型的合同(这也有助于理解您的问题域。您现在可以轻松地查看自由度实际来自哪里,系统有多少种不同的行为,您可以保留核心实现清理。你也可以测试核心代码库,你可以记录每个行为契约的要求,你可以用单元测试方式测试行为实现,而不是在体内" - 混乱到核心代码库。
  2. 针对步骤1中定义的合同实现每个行为。在行为实现中接受一些重复的代码,而不是过度设计并尝试分解这些行为之间的共性。把事情简单化。并对每个人进行测试。
  3. 结果:具有0个配置选项的行为实现的集合以及具有0个配置选项的核心代码库。最后一步是选择客户项目的行为实现,如果有特殊内容,可以编写新的实现。

    如果你这样做了,你将永远幸福地生活,而不会改变合同和核心系统。如果您错过了一些完美的设计,那么您将进行一些迭代,直到您找到最佳的合约界面设计,以便您的核心代码库变得稳定。

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

答案 1 :(得分:2)

  • 交换机应该是运行时交换机,而不是编译时交换机。原因是,交换机应该可以在不重新部署的情况下运行。
  • 实现运行时条件逻辑有两种可能性:
    1. if-then-else(或switch-case用于多状态切换)
    2. Polymorphy,需要面向对象的编程语言。

我个人更喜欢使用普通的if-then-else构造,并在适用时添加评论TODO: Remove when feature has been tested.

请记住每个功能标记is a technical debt。不要过度使用它们。我建议不要将它们用于业务逻辑。

然而,关于你的意大利面条业务切换,我会建议重构。

  • 任何函数的嵌套深度都不应大于2。如果有,则拆分为具有有意义名称的多个函数。
  • 消除双重否定。
  • De Morgan's laws对于重新组织条件逻辑特别有用。

如果这还不够,您可以使用graph(例如决策流程图)或Matrix为业务逻辑建模,并使用相应的标准算法。