我正在使用 Stateless 在多个类中实现 FSM。(http://code.google.com/p/stateless/)
我想使用一个基类来触发触发器和日志记录等。我还想强制任何继承我的 baseFSM 类的类都使用它们自己的本地状态和触发器来实现 StateMachine。
但是我的问题是,枚举不能被抽象或传递给函数。
顺便说一句,Stateless 说“对任何 .NET 类型(数字、字符串、枚举等)的状态和触发器的通用支持”所以如果有更好的方法来解决这个问题,请告诉我。
理想情况下,这就是我想要实现的(或可以以相同方式工作的东西)。
BaseFSM 类:
public abstract class BaseFSM : IStateMachine
{
#region Implementation of IStateMachine
public ICall LocalCall { get; set; }
#endregion
internal abstract enum State {}
internal abstract enum Trigger {}
internal abstract StateMachine<State, Trigger> fsm { get; set; }
public abstract void Fire(Enum trigger);
}
一个实现 BaseFSM 的类:
class Incoming_Initial : BaseFSM
{
private enum State
{
WaitForCallToBeAnswered,
CallConnected,
CallNeverConnected,
CheckForCustomIntro,
PlayIntro,
PlayPleaseEnterPin,
ReadLanguageSettings,
ChooseLanguage,
ValidatePIN,
PINWasInvalid,
IdentifyUser
}
private enum Trigger
{
Yes,
No,
DigitPressed,
PromptDonePlaying,
PromptTimerElapse,
Done
}
public Incoming_Initial(ICall call)
{
LocalCall = call;
fsm = new StateMachine<this.State, this.Trigger>(State.WaitForCallToBeAnswered);
....
或者我什至会采取这样的做法:
public class myStateMachine
{
private enum State{}
private enum Trigger{}
private StateMachine<State, Trigger> stateMachine;
public myStateMachine (Enum _states, Enum _triggers, Enum _startState)
{
State = _states;
Trigger = _triggers;
stateMachine = new StateMachine<State, Trigger>(_startState);
}
}
任何关于我如何实现这一点的见解将不胜感激!
编辑:我的最终目标是使用 Stateless 来实现具有约 40 个不同 FSM 的 IVR ( IVR ) 系统。状态机将负责调用流程以及用户如何与系统交互。我已经有一个演示状态机工作,但状态和触发器是该类的本地。
我只是想看看我是否可以将状态机拉到基类中,这样我就不必将状态机传递给辅助函数。
如果我可以将状态机放在基类中,我想我可以使用一组触发器(这些将是来自电话呼叫的事件,如 CallConnected、UserPressedDigit、CallDisconnected、PromptDonePlaying 等)并且只需要为每个 FSM 实现状态.
感谢@phoog,回答(至少我是如何使用它的):
public abstract class BaseFSM <TState> : IStateMachine
{
#region Implementation of IStateMachine
public ICall LocalCall { get; set; }
#endregion
public enum Triggers
{
Yes = 0,
No,
DigitPressed,
PromptDonePlaying,
PromptTimerElapse,
Done
}
protected IList<TState> States { get; set; }
protected StateMachine<TState, Triggers> fsm { get; set; }
...
class Incoming_Initial : BaseFSM<Incoming_Initial.State>
{
internal enum State
{
WaitForCallToBeAnswered,
CallConnected,
CallNeverConnected,
CheckForCustomIntro,
PlayIntro,
PlayPleaseEnterPin,
ReadLanguageSettings,
ChooseLanguage,
ValidatePIN,
PINWasInvalid,
IdentifyUser
}
public Incoming_Initial(ICall call)
{
LocalCall = call;
LocalCall.CallEventHandler += new CallEventHandler(LocalCall_CallEventHandler);
States = (State[]) Enum.GetValues(typeof (State));
fsm = new StateMachine<State, Triggers>(State.WaitForCallToBeAnswered);