純軽量ステートマシンステートレス

  多くのビジネス・システムの開発は、必然的に状態の変化があるだろう、状況が完了するために、ワークフローを使用することは通常可能ですが、簡単なシナリオ、ワークフロー感のある少し小さい幸運、このような順序の事業として、注文状況について使用するのに十分であり、たとえ、それ以外の使用を減らすためにスイッチを過ごすことができますしても、単純な場合には、そうでなければ、何かを失うことになるが、状態に関連した変化はない多くは、可能です。より良いプロセス全体を最適化するには、この時間は、いくつかの問題を解決するために、アカウントに状態モデルの使用がかかります。

  机状态ステートレスGitHubの:https://github.com/dotnet-state-machine/stateless 

 

ステートマシンと状態モデル

1、状態モデルは:「内部状態の変化は、それが属するオブジェクトクラスを変更するために現れた場合、オブジェクトがその動作を変更することができます。」。(状態パターン:「内部状態はオブジェクトがそのクラスを変更することが表示されます変更したときにオブジェクトがその動作を変更することを許可します。」。)

  この定義については、理解することができるかを理解するには少し抽象的、作業:所有者の状態を状態に委託オブジェクトの動作を変更するためには、状態が(もちろん、あなたはまた、オブジェクトの状態を破棄することができます)状態の自分自身だけ所有者を持って、職務を行うためにオブジェクトの状態を変更します。

 

2、ステートマシン:「選択状態のフローチャートは、現在実行中の操作に応じて、所定の条件の現在の状態に応じて新しい状態に変更されます。」

  状態機械は、4つの要素、すなわち、現在の状態、条件、アクション、状態時間を有しています。前記現在の状態及び条件「の」動作状態ビューと「効果」。

  • 現在の状態は - オブジェクトの現在の状態です
  • 条件 - 条件が満たされた場合には、現在のオブジェクトがアクションをトリガーします
  • アクション - 条件が満たされた後、アクションが実行さ
  • 次の状態 - 条件が満たされた後、オブジェクトの新しい現在の状態。サブ状態は、一度トリガ、それは、現在の状態のサブ状態の点で比較的現在の状態となります

 

図3に示すように、状態遷移図は、: UMLモデリングでは、原因イベントの発生にすべての可能な状態と状態のうち特定オブジェクトの移動を記述するために使用される通常の可視、及び変形が生じ、状態マシンが配置されています前提に従い、どのような行為

  

 

二、ステートレス機能

  ステートレスは、C#に基づいてステートマシンを作成するためのシンプルなライブラリです。ネット規格に基づいて、それは.NET Frameworkおよび.NETのコアプロジェクトで使用することができます。ソースアドレス:https://github.com/dotnet-state-machine/stateless

  Laijiangjiangステートレスな特長コールのケースを使用するには:

// 初期化状態マシン
の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、功能特性

 状态机常见功能:

  • 支持所有.Net类型的状态和触发器(数字、字符串、枚举等等)
  • 分层状态
  • 状态的进入和退出事件
  • 用卫语句来支持条件转换
  • 内省

 提供了一些有用的扩展:

  • 支持外部的状态存储(例如:由ORM跟踪属性)
  • 参数化触发器
  • 可重入状态
  • 导出DOT格式图

 

2、分层状态

  在以下例子中,OnHold状态是Connected状态的子状态。这意味着电话挂起的时候,还是连接状态的,通过IsInState()方法,可以判定是否当前状态处于父状态下的子状态,比如IsInState(State.Connected)能够返回true,说明当前OnHold状态是处于Connected状态的。

phoneCall.Configure(State.OnHold)
  .SubstateOf(State.Connected)
  .Permit(Trigger.TakenOffHold, State.Connected)
  .Permit(Trigger.PhoneHurledAgainstWall, State.PhoneDestroyed);

 

3、状态的进入和退出事件

  在前面的例子中,StartCallTimer()方法会在通话连接时执行,StopCallTimer()方法会在通话结束时执行,对应的便是,进入该状态与脱离该状态时候执行的事件。当电话的状态从已连接(Connected)变为挂起(OnHold)时, 不会触发StartCallTimer()方法和StopCallTimer()方法, 这是因为OnHold是Connected的子状态,对于进入和退出事件的处理者,可以传参提供触发动作,现状和次状信息。

  

 

4、外部状态存储

  有时候,当前对象的状态需要来自于一个ORM对象,或者需要将当前对象的状态保存到一个ORM对象中,UI框架需要存储一个状态到绑定属性中。为了支持这种外部状态存储,StateMachine类的构造函数支持了读写状态值。如代码里,通过使用myState可以去存储和获取状态值。

var stateMachine = new StateMachine<State, Trigger>(
  () => myState.Value,
  s => myState.Value = s
);

 

5、内省

  该状态机可以通过StateMachine.PermittedTriggers属性获取当前状态下可以触发的触发器列表。并能够使用StateMachine.GetInfo()获取状态相关的配置信息。

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、参数化触发器

  支持将强类型参数提供给触发器,使用方法PermitDynamic()配置状态机时,能够通过触发器参数动态选择目标状态。

var assignTrigger = stateMachine.SetTriggerParameters<string>(Trigger.Assign);

stateMachine.Configure(State.Assigned)
    .OnEntryFrom(assignTrigger, email => OnAssigned(email));
    
stateMachine.Fire(assignTrigger, "[email protected]");

 

8、忽视转换和重入状态

  如果触发了一个没有配置过的线路,将会抛出一个异常,通过使用Ignore方法,忽视一些触发,当触发了此类触发器时,不会抛出异常,而改为忽略该次触发。

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.orgviz.jsdot command line工具。

诸如生成的字符串在viz.js中解析的状态机图形。

  

 

10、异步触发

  该状态机支持异步操作,对于Entry/Exit方法等都有相应的异步方法,带Async结尾,并且对于触发也有异步方法FireAsync(),需要注意的是,尽管使用了异步,但仍然是单线程操作,不能被多个线程同时使用。

stateMachine.Configure(State.Assigned)
    .OnEntryAsync(async () => await SendEmailToAssignee());
    
await stateMachine.FireAsync(Trigger.Assigned);

 至此,对于状态机Stateless的功能差不多了解完毕了,开始将状态机融入到项目中实际使用起来,也已经加入到日程中。

 

2019-09-22,望技术有成后能回来看见自己的脚步

おすすめ

転載: www.cnblogs.com/CKExp/p/11564882.html