日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.Net轻量状态机Stateless

發布時間:2023/12/4 asp.net 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .Net轻量状态机Stateless 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  很多業務系統開發中,不可避免的會出現狀態變化,通常采用的情形可能是使用工作流去完成,但是對于簡單場景下,用工作流有點大財小用感覺,比如訂單業務中,訂單狀態的變更,涉及到的狀態量不是很多,即使通過簡單的if-else也能足夠使用,甚至是用上switch去減少if-else的使用,都是可以的,盡管這會喪失某些東西。為更好的優化整個流程,此時會考慮到使用狀態模式來解決一些問題。

  Stateless狀態機GitHub:https://github.com/dotnet-state-machine/stateless ?

一、狀態模式與狀態機

1、狀態模式:"允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它所屬的類 "。(State Pattern:?"Allow an object to alter its behavior when its internal state changes. The object will appear to change its class ".)

  對于這個定義,有點抽象,變通理解一下可以這么理解:狀態擁有者將變更行為委托給狀態對象,狀態擁有者本身只擁有狀態(當然也可以拋棄狀態對象),狀態對象履行變更職責。

?

2、狀態機:"依照指定的狀態流程圖,根據當前執行的動作,將當前狀態按照預定的條件變更到新的狀態?"。

  狀態機有4個要素,即現態、條件、動作、次態。其中,現態和條件是“因”, 動作和次態是“果”。

  • 現態 - 是指當前對象的狀態

  • 條件 - 當一個條件滿足時,當前對象會觸發一個動作

  • 動作 - 條件滿足之后,執行的動作

  • 次態 - 條件滿足之后,當前對象的新狀態。次態是相對現態而言的,次態一旦觸發,就變成了現態

?

3、狀態遷移圖:"在UML建模中,常常可見,用來描述一個特定的對象所有可能的狀態,以及由于各種事件的發生而引起的狀態之間的轉移和變化,也是配置狀態機按照何種行徑的前提?"。

  

?

二、Stateless功能介紹

  Stateless是一個基于C#創建狀態機的簡單庫。基于.Net Standard實現,在.Net Framework和.Net Core項目中都可以使用。源碼地址:https://github.com/dotnet-state-machine/stateless

  以一個打電話的使用案例來講講Stateless的功能:


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, "joe@example.com");

?

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.org和viz.js的dot command line工具。

  諸如生成的字符串在viz.js中解析的狀態機圖形。

  

?

10、異步觸發

  該狀態機支持異步操作,對于Entry/Exit方法等都有相應的異步方法,帶Async結尾,并且對于觸發也有異步方法FireAsync(),需要注意的是,盡管使用了異步,但仍然是單線程操作,不能被多個線程同時使用。

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

await stateMachine.FireAsync(Trigger.Assigned);

 至此,對于狀態機Stateless的功能差不多了解完畢了,開始將狀態機融入到項目中實際使用起來,也已經加入到日程中。

原文鏈接:https://www.cnblogs.com/CKExp/p/11564882.html


.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總?http://www.csharpkit.com?


總結

以上是生活随笔為你收集整理的.Net轻量状态机Stateless的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。