English 中文(简体)
状态机适用于处理促销系统中的状态变化吗?
原标题:
  • 时间:2009-03-23 14:15:55
  •  标签:

I m developing sales promotion system and I just stepped on something that could be probably handled with state machine pattern, but I have no experiences with state machines yet. Maybe the state machine is totally useless in this situation :) So I have a sales promotion which has some duration, some assigned customers, products, discounts etc. Each promotion also has it s state. There s about 5 states. The transitions between states are strictly defined - it s not possible to change state 1 to state 3 directly - user has to change state to 2 first. There re some limitations like "it s not possible to add m或e products when promotion is in state 3-5". Or limitations like "only super-users can edit promotion costs when it s in state 3-5".

我刚读到关于http://www.codeplex.com/SimpleStateMachine,但我不确定对于这种情况来说是否太复杂。我可以使用以下内容来处理服务层中的状态逻辑:

if (promotion.state == statesReposit或y.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等服务,以减少代码的耦合,但可能有一些更好的解决方案我目前看不到。

最佳回答

对于一个状态机来说,五个状态并不太复杂,但我认为,试图专门或明确地处理一些转换会遇到一些问题。以下是一些提示:

  • 除非能够以有意义的方式标记状态,否则状态机是没有帮助的。“状态3”毫无意义;你需要称之为有用的东西,比如“提升”、“活跃”、“完成”等等。

  • 状态机模式的一部分假设您有一个独立的实体,它了解状态以及如何在状态之间转换。例如,在您的示例中,不应该有一个类似于ChangePromotionStatus()的方法,如果不允许状态,它就会爆炸。状态机应该简单地防止无法发生的转换。

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

问题回答

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

理想情况下,适合由状态机管理的域实体将具有某种状态,作为状态机的状态,并将引发事件,状态机可以使用这些事件来确定何时进行转换。

然而,如果你的状态确实是完全顺序的,也就是说,它们总是向前或向后移动一步,我不确定状态机是否有意义,因为不需要特殊的上下文来选择下一个状态,你只能向后或向前移动,因此,任何与下一个/上一个逻辑相结合的有序状态列表(如枚举)都应该足够了——但现实世界中的进程很少是严格线性的,尽管它们乍看起来可能是线性的。





相关问题
热门标签