多くのビジネス・システムの開発は、必然的に状態の変化があるだろう、状況が完了するために、ワークフローを使用することは通常可能ですが、簡単なシナリオ、ワークフロー感のある少し小さい幸運、このような順序の事業として、注文状況について使用するのに十分であり、たとえ、それ以外の使用を減らすためにスイッチを過ごすことができますしても、単純な場合には、そうでなければ、何かを失うことになるが、状態に関連した変化はない多くは、可能です。より良いプロセス全体を最適化するには、この時間は、いくつかの問題を解決するために、アカウントに状態モデルの使用がかかります。
ステートマシンと状態モデル
1、状態モデルは:「内部状態の変化は、それが属するオブジェクトクラスを変更するために現れた場合、オブジェクトがその動作を変更することができます。」。(状態パターン:「内部状態はオブジェクトがそのクラスを変更することが表示されます変更したときにオブジェクトがその動作を変更することを許可します。」。)
2、ステートマシン:「選択状態のフローチャートは、現在実行中の操作に応じて、所定の条件の現在の状態に応じて新しい状態に変更されます。」
// 初期化状態マシン のvar PhoneCall = 新しい新しいステートマシン<状態、トリガー> (State.OffHook)。 // プロセス構成 phoneCall.Configure(State.OffHook) .Permit(Trigger.CallDialled、State.Ringing)。 phoneCall.Configure(State.Ringing) .Permit(Trigger.CallConnected、State.Connected)。 phoneCall.Configure(State.Connected) .OnEntry(() => StartCallTimer()) .OnExit(() => StopCallTimer()) .Permit(Trigger.LeftMessage, State.OffHook) .Permit(Trigger.PlacedOnHold, State.OnHold); // ... //触发行为 phoneCall.Fire(Trigger.CallDialled); Assert.AreEqual(State.Ringing, phoneCall.Stat
1、功能特性
2、分层状态
phoneCall.Configure(State.OnHold)
.SubstateOf(State.Connected)
.Permit(Trigger.TakenOffHold, State.Connected)
.Permit(Trigger.PhoneHurledAgainstWall, State.PhoneDestroyed);
3、状态的进入和退出事件
4、外部状态存储
var stateMachine = new StateMachine<State, Trigger>( () => myState.Value, s => myState.Value = s );
5、内省
public IEnumerable<TTrigger> PermittedTriggers { get { return GetPermittedTriggers(); } } //返回StateMachineInfo对象,包含状态及触发器列表。 _machine.GetInfo();
6、卫语句
phoneCall.Configure(State.OffHook) .PermitIf(Trigger.CallDialled, State.Ringing, () => IsValidNumber) .PermitIf(Trigger.CallDialled, State.Beeping, () => !IsValidNumber)
7、参数化触发器
var assignTrigger = stateMachine.SetTriggerParameters<string>(Trigger.Assign); stateMachine.Configure(State.Assigned) .OnEntryFrom(assignTrigger, email => OnAssigned(email)); stateMachine.Fire(assignTrigger, "[email protected]");
8、忽视转换和重入状态
phoneCall.Configure(State.Connected)
.Ignore(Trigger.CallDialled);
另外,一个状态能够使用PermitReentry方法配置为重复进入(从本状态到本状态),entry和exit事件也会被再次触发。
stateMachine.Configure(State.Assigned)
.PermitReentry(Trigger.Assigned)
.OnEntry(() => SendEmailToAssignee());
默认情形下,必须明确忽略哪些触发器. 当未配置的触发器被触发时默认是抛出异常,可以通过使用OnUnhandledTrigger配置状态机覆写处理异常情形。
stateMachine.OnUnhandledTrigger((state, trigger) => { });
9、导出DOT格式图
phoneCall.Configure(State.OffHook) .PermitIf(Trigger.CallDialled, State.Ringing, IsValidNumber); string graph = UmlDotGraph.Format(phoneCall.GetInfo());
UmlDotGraph.Format()方法返回代表状态机的字符串,使用DOT graph语言格式。这个可以被支持DOT graph语言的工具渲染。像graphviz.org
10、异步触发
stateMachine.Configure(State.Assigned) .OnEntryAsync(async () => await SendEmailToAssignee()); await stateMachine.FireAsync(Trigger.Assigned);
至此,对于状态机Stateless的功能差不多了解完毕了,开始将状态机融入到项目中实际使用起来,也已经加入到日程中。
2019-09-22,望技术有成后能回来看见自己的脚步