什么设计模式可以用于功能切换



我工作的公司在功能开关方面做得太过火了——配置键可以根据特定条件打开/关闭特定行为。Martin Fowler实际上把它们称为业务切换(http://martinfowler.com/bliki/FeatureToggle.html)。

我们有许多客户端都使用相同的服务,但每个客户端都想要略有不同的行为。更糟糕的是,许多公司希望用户的特定子组看到不同的行为。因此,我们使用业务切换。这些切换已经变成了if/else逻辑的意大利面球,偶尔会有意外的交互。

有什么设计模式在管理这样的情况有用吗?

干杯!

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

我个人更喜欢使用普通的if-then-else结构,在适用的情况下用TODO: Remove when feature has been tested.注释来修饰。

请记住,每个特性标志都是技术债务。不要过度使用。我不建议在业务逻辑中使用它们。


但是,对于您的业务切换,我建议进行重构。

  • 任何函数的嵌套深度都不能大于2。如果有,拆分成多个有意义的函数。
  • 消除双重否定。
  • De Morgan定律对于重组条件逻辑特别有用。

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

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

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

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

那么工作流可能看起来有点像这样:

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

我认为在没有大量配置的情况下处理这个问题的设计是:

  1. 为每个处理步骤划分一个行为类型。在预处理步骤的示例中,这可能类似于IInputShaper,负责将特定类型的输入数据转换为内部格式并执行一些预处理。可能这可以再次拆分:IInputFitter, IPreprocess。对于工作流中的其他步骤,请相应地执行。这为您留下了许多行为类型的契约(这也有助于理解您的问题域)。你现在可以很容易地看到自由度实际上来自哪里,系统有多少种不同的行为,你可以保持核心实现的整洁。你也可以测试核心代码库,你可以记录每个行为契约的需求,你可以以单元测试的方式测试行为实现,而不是"在体内"——混乱在核心代码库中。
  2. 根据步骤1中定义的契约实现每个行为。在行为实现中接受一些重复的代码,而不是过度设计并试图找出这些行为之间的共性。保持简单。并对他们每个人进行测试。

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

如果你做对了,你将从此过上幸福的生活,而不需要改变合同和核心系统。如果你错过了完美的设计,你将会有一些迭代,直到你找到最好的合约接口设计,这样你的核心代码库就会变得稳定。

用这种方法,你也会有一个更容易的时间来估计工作和写报价给新客户。如果你已经有了所有的行为实现,或者你需要编写一些新的行为实现,你可以简单地在引用阶段进行检查。如果你记录了一开始写它们花了多长时间,你甚至可以很好地猜测它将花费多少小时。

相关内容

  • 没有找到相关文章

最新更新