状态机 - 嵌入式开关

时间:2017-01-23 20:37:01

标签: c# asp.net state-machine

我正在开发我的第一个asp.net mvc Web应用程序。我有一个可以处于14种不同状态的表单,根据当前状态,转换到其他状态是或不可能的。每个当前状态平均有3-5个不同的下一个状态。

我现在需要做的是在某些状态转换期间触发操作。根据初始状态和最终状态,触发某些操作(例如,发送电子邮件)。

我是通过使用switch语句开始的:

switch ((int)currentState)
        {
            //Initial
            case -1:
                {
                    switch ((int)nextState)
                    {
                        //Next state: Inv. is waiting
                        case 1: 
                            {
                                //Send email to x
                                emailHelper.Send(x,msg)
                                //Send email to Y
                                emailHelper.Send(y,anotherMsg)

                            }
                        case 2: 
                            {
                                doSomethingelse()
                            }
                            break;
                    }
                    break;
                }
            //Inv is waiting
            case 1:
                {
                    switch ((int)nextState)
                    {
                        ...
                    }
                }
  ...

我认为这个解决方案对我来说很好,但我想知道我是否可以使用更好的东西......有什么建议吗?

3 个答案:

答案 0 :(得分:2)

也许您可以使用数据结构来存储状态和转换。例如,状态机可以是Dictionary<int, State>,其中State可以像

一样简单
struct State {
  Dictionary<int, Action> transitions;
}

执行状态转换然后看起来像

var action = states[currentState].transitions[nextState];
action();
currentState = nextState;

当然,这个解决方案可以更加封装,可以使用检查转换是否存在,但这是它的要点

答案 1 :(得分:2)

如果性能根本不是问题,并且您唯一感兴趣的是紧凑型代码,请考虑

import { $ } from "jquery";

$("box").click(function() {
    alert("Hello world!!");
});

您还可以等待C#7.0并使用其新形式的switch statement。像这样:

switch(string.Format(CultureInfo.InvariantCulture, "{0} {1}", currentState, nextState))
{
    case "-1 1":
        //Send email to x
        emailHelper.Send(x,msg);
        //Send email to Y
        emailHelper.Send(y,anotherMsg);
        break;
    case "-1 2":
        doSomethingelse();
        break;
    ....
}

答案 2 :(得分:1)

(伪代码)

class StateHandler
{
    int CurrentState;
    int NextState;
    Action MyAction;

    public void Eval(int currentState, int nextState)
    {
        if(currentState == this.CurrentState && nextState == this.NextState)
        {
             this.MyAction();
        }
    }
}

创建一个List并使用所有已知的状态转换填充它。然后只需迭代List并在每个项目上调用Eval()。

List<StateHandler> handlers = new List<StateHandler>();
handlers.Add(new StateHandler() 
{ 
   currentState = 0, 
   nextState = 1,  
   () => doSomeWork() 
}
handlers.Add(new StateHandler() 
{ 
   currentState = 3, 
   nextState = 4,  
   () => doSomeOtherWork() 
}