我正在尝试实现状态机。该方案是如果提交了文档,则将其发送以供审核,然后再批准。
但是它引发了一个错误,即已审核->批准过渡无效。
下面的代码可能会带来更好的效果。
为什么会引发错误?我已经确保一切正常,但仍然可以。
public enum ProcessState
{
Submitted,
Reviewed,
Approved
}
public enum Command
{
Submit,
Review,
Approve
}
public class Process
{
class StateTransition
{
readonly ProcessState CurrentState;
readonly Command Command;
public StateTransition(ProcessState currentState, Command command)
{
CurrentState = currentState;
Command = command;
}
public override int GetHashCode()
{
return 17 + 31 * CurrentState.GetHashCode() + 31 * Command.GetHashCode();
}
public override bool Equals(object obj)
{
StateTransition other = obj as StateTransition;
return other != null && this.CurrentState == other.CurrentState && this.Command == other.Command;
}
}
Dictionary<StateTransition, ProcessState> transitions;
public ProcessState CurrentState { get; private set; }
public Process()
{
CurrentState = ProcessState.Submitted;
transitions = new Dictionary<StateTransition, ProcessState>
{
{ new StateTransition(ProcessState.Submitted, Command.Review), ProcessState.Reviewed },
{ new StateTransition(ProcessState.Reviewed, Command.Approve), ProcessState.Approved },
};
}
public ProcessState GetNext(Command command)
{
StateTransition transition = new StateTransition(CurrentState, command);
ProcessState nextState;
if (!transitions.TryGetValue(transition, out nextState))
throw new Exception("Invalid transition: " + CurrentState + " -> " + command);
return nextState;
}
public ProcessState MoveNext(Command command)
{
CurrentState = GetNext(command);
return CurrentState;
}
}
public class Program
{
static void Main(string[] args)
{
Process p = new Process();
Console.WriteLine("Current State = " + p.CurrentState);
Console.WriteLine("Command.Submit: Current State = " + p.MoveNext(Command.Submit));
Console.WriteLine("Command.Review: Current State = " + p.MoveNext(Command.Review));
Console.WriteLine("Command.Approve: Current State = " + p.MoveNext(Command.Approve));
Console.ReadLine();
}
}
更新:
这是错误部分:
public ProcessState GetNext(Command command)
{
StateTransition transition = new StateTransition(CurrentState, command);
ProcessState nextState;
if (!transitions.TryGetValue(transition, out nextState))
throw new Exception("Invalid transition: " + CurrentState + " -> " + command);
return nextState;
}
答案 0 :(得分:1)
这可以使您的示例Main
正常运行。问题是您的transitions
词典中没有Command.Approve
的条目。
public Process()
{
CurrentState = ProcessState.Submitted;
transitions = new Dictionary<StateTransition, ProcessState>
{
//This does nothing. Submitted -> Submitted
{ new StateTransition(ProcessState.Submitted, Command.Submit), ProcessState.Submitted },
//Submitted -> Reviewed
{ new StateTransition(ProcessState.Submitted, Command.Review), ProcessState.Reviewed },
//Reviewed -> Submitted. Do you want this?
{ new StateTransition(ProcessState.Reviewed, Command.Submit), ProcessState.Submitted },
//I added this. Reviewed -> Approved
{ new StateTransition(ProcessState.Reviewed, Command.Approve), ProcessState.Approved }
};
}
输出:
Command.Submit:当前状态=已提交
Command.Review:当前状态=已审核
Command.Approve:当前状态=已批准
注意,我没有检查所有的状态机转换。我只是添加了缺失的那个。