【问题标题】:is state machine suitable for handling state changes in sales-promotion system?状态机是否适合处理促销系统中的状态变化?
【发布时间】:2009-03-23 14:15:55
【问题描述】:

我正在开发促销系统,我刚刚踩到了一些可能用状态机模式处理的东西,但我还没有使用状态机的经验。也许状态机在这种情况下完全没用:) 所以我有一个促销,它有一定的持续时间,一些指定的客户,产品,折扣等。每个促销也有它的状态。大约有5个州。状态之间的转换是严格定义的——不可能直接将状态 1 更改为状态 3——用户必须先将状态更改为 2。有一些限制,例如“促销处于状态 3-5 时无法添加更多产品”。或者像“只有超级用户可以在状态 3-5 时编辑促销费用”这样的限制。

我刚刚阅读了有关 http://www.codeplex.com/SimpleStateMachine 的信息,但我不确定它对于这种情况是否不太复杂。我可以使用以下方式处理服务层中的状态逻辑:

if (promotion.state == statesRepository.GetState3() && false == loggedUser.IsInRole("superUser")){
   throw new PromotionStateException("user not allowed to edit promotion in this status");
}
...

public void ChangePromotionStatus(promotion, newStatus){
  if (promotion.Status == status1 && newStatus != statesRepo.GetState2()){
    throw new StateTransitionException("unable to change from status 1 to " + newStatus);
  }
}

但我不喜欢这种代码 - 必须有更好的方法 :) 有人有建议吗?我当然可以分离关注点并开发诸如 PromotionStatusChangeReviewService、PromotionEditPermissionService 等服务,以减少代码耦合,但目前可能有一些更好的解决方案我看不到。

【问题讨论】:

    标签: design-patterns state-machine


    【解决方案1】:

    五种状态对于状态机来说并不太复杂,但我认为您在尝试对一些转换进行特殊或显式处理时遇到了一些问题。这里有一些提示:

    • 除非您可以以有意义的方式标记状态,否则状态机没有帮助。 “状态 3”没有任何意义;您需要将其命名为“已升级”、“活动”、“已完成”等有用的名称。

    • 状态机模式的一部分假定您有一个分离的实体,它了解状态以及如何在它们之间转换。例如,在您的示例中,您不应该有像 ChangePromotionStatus() 这样的方法,如果不应该允许该状态,它就会爆炸。状态机应该简单地防止不能发生的转换。

    • 如果可能的转换数量很小且定义明确,并且标记它们是有意义的,我还建议也命名转换。如果转换都做同样的事情但方式略有不同,这可能特别有用。

    【讨论】:

    • 为简单起见,我将状态标签简化为数字 - 它们被命名为“提议”、“确认”、“计划”,.... 到“ChangePromotionStatus”-反应 - 我理解转换逻辑应该放在特定的班级。我无法弄清楚如何将它们结合在一起。我会阅读更多关于 SM 的内容,谢谢。
    【解决方案2】:

    John 一针见血——您希望您的流程(使用状态机建模)与您的域实体分离。您的域实体可能不应该直接知道它们在状态机中使用,状态机将根据某些事件管理将它们从状态转换为状态的工作,但它们了解业务他们所处的每个状态的含义,并且能够执行或应用与这些状态相关的业务规则。

    理想情况下,适合由状态机管理的域实体将具有某种状态,充当状态机的状态,并引发事件,状态机可以使用这些事件来确定何时过渡是适当的。

    但是,如果您的状态确实是 完全 连续的 - 即它们总是按 a-b-c-d-e 或向后和向前恰好一步,我不确定状态机是否有意义,因为有选择下一个状态不需要特殊的上下文 - 你只能向后或向前走,所以任何有序的状态列表(例如枚举)加上 Next/Previous 逻辑就足够了 - 但现实世界的过程很少是严格线性的,即使他们乍一看可能会脸红。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-27
      • 2012-05-22
      相关资源
      最近更新 更多