重构乐趣:处理复杂的状态

时间:2009-03-09 04:35:51

标签: refactoring

假设我们有一个Web应用程序,应该让用户填写表单,然后在后端工作流引擎中创建一个票证。这个表格将继续成为客户查看正在发生的事情的门户。有些表格会直接创建票证;其他人必须在生成机票之前得到其他人的批准,他们也可能被拒绝。这件事发送电子邮件,跟踪表格问题的答案,跟踪任何上传的附件,并记录“更新”,因为各种行动都会改变表格的状态。

决定在首次提交或保存表单时要做什么的业务逻辑开始变得毛茸茸,我正在寻找重构它的方法。我已经开始研究状态/策略模式,但似乎所有的逻辑都需要最终集中在一个地方。此外,对于答案/附件/日志条目的所有依赖性,它使注入模拟变得复杂,因为它有很多必须跟踪。

这是表单对象的“保存”功能的伪代码布局,简化了......它开始变得讨厌,我试图看看我是否能以某种方式使它更清洁。

if(this.isvalid)
{
    if(isNewForm && !this.needsApproval) //just created, so start up a ticket
    {
        CreateTicket();
    }

    if(!isNewForm && justApproved) //pulled from the DB earlier, and was just approved
    {
        CreateTicket();
    }

    if(!isNewForm && justDenied) //pulled from the DB earlier, and was just denied
    {
        this.needsApproval = false;
        this.closed = true;
    }

    if(isNewForm)
    {
        SendNewFormEmail();
        if(this.NeedsApproval)
        {
            SendNeedsApprovalEmail();
        }

        this.CommentEntries.Add("Request submitted.");
    }
    else if(justApproved)
    {
        SendApprovalEmail();
        this.CommentEntries.Add("Request approved.");
    }
    else if(justDenied)
    {
        SendDenialEmail();
        this.CommentEntries.Add("Request denied.");
    }   

    this.Save();

    this.Answers.Save();
    this.Attachments.Save();
    this.CommentEntries.Save();
}

3 个答案:

答案 0 :(得分:2)

我最近一直在考虑国家机器,我发现以下提议非常有希望。我希望我能告诉你它的工作真的很棒,但我还没有那么远。我可以告诉你,它看起来比我试过的任何解决方案都要好。这是链接.. Hierarchical State Machine

答案 1 :(得分:0)

if (isNewForm) {

   if (JustDenied) {
      ...
   }

   if (JustApproved) {
      ....
   }

} else {
   ... not a new form ...
}

我不确定你的处理方式是JustDenied,但也许是:

switch (FormState) {
case JustApproved:
   ....
case JustDenied:
   ....
}

它的伪代码,很难说是否可行。但是,是的,我同意你发布的内容开始像意大利面。

答案 2 :(得分:0)

我认为这是Workflow Foundation的优秀候选人。

问题不是写一个复杂的状态机,而是处理一个企业的动态(有时候看起来也像意大利面;))。规则改变,代码需要改变,当你自己发现时,可维护性很容易成为这里的噩梦......