<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      狀態機

      引言

      在業務處理中, 經常需要處理業務對象的狀態轉換, 比如 bug 狀態管理、訂單狀態管理等, 這類問題可依照狀態的復雜度,可以有不同的解決方案。

      1. 簡單的順序狀態管理
        如果狀態數量很少,同時狀態是按照一個方向流轉,就可以歸到這類。 對應的解決方案很簡單, 在業務對象中增加一個表示狀態的枚舉字段即可。

      2. 復雜的 BPM 狀態管理
        這里復雜的狀態管理, 典型特征是包含 BPM 的 split/join, 比如合同的會簽, 對應的解決方案就使用重量級的工作流引擎, 比如 Java 的 flowable、camunda、 activiti, C#的 Elsa Workflows 等。

      3. 中等復雜的狀態管理
        我將不含 BPM 的 split/join 情形的都歸到中等復雜程度,最佳解決方案是使用狀態機,在每個業務對象中內嵌一個狀態機,由狀態機復雜狀態轉換。

      對于簡單的狀態管理,往往后期會逐漸會變得不那么簡單,所以, 對于簡單的狀態管理,我也推薦使用狀態機,甚至這么說,只要不涉及到 BPM split/join, 使用狀態機都是最佳方案。

      狀態機的幾個概念

      1. 狀態轉換 transition
        目標狀態僅由前置狀態經過一個事件觸發實現狀態轉換。

      2. 守衛條件 Guard condition
        從前置狀態可以無條件地通過一個觸發條件轉換到目標狀態,也可以有條件地通過觸發事件轉換。
        這里的條件在狀態機中被叫做 guard condition。
        需要說明的是, guard condition 不應該被理解成狀態轉換的 pre check 條件,而是不同的目標狀態的的區分條件。

       (A) ----triggerB (condition1) --> (B1)
        |
        | -----triggerB (condition2) --> (B2)
      

      Java 狀態機

      我比較喜歡 C# Stateless 類庫,在 Java 中也有很多狀態機類庫, 比如 Squirrel、Spring Statemachine、EasyFlow、Apache SCXML。 和 C# Stateless 風格最像的是 Squirrel, C# Stateless 有的功能它基本都有,也可以導出 graphviz 流程圖,只是缺少導出 mermaid 流程圖,考慮到 mermaid 流程DSL非常簡單, 自己實現也很簡單。

      Squirrel:https://github.com/hekailiang/squirrel

      C# Stateless 狀態機開源庫

      Stateless github 是 C#中最流行的狀態機實現,功能非常強大:

      • 支持守衛 condition
      • 支持帶參數的 trigger
      • 內建很多事件可供綁定
      • 可進行觸發檢查
      • 支持父子狀態

      Tips: 使用 PermitIf() 啟用守衛 condition時,可以增加一個說明類型參數, 該參數可以在導出流程圖時輸出到trigger的label上,這個說明對于理解狀態轉換非常有幫助。 無條件的狀態轉換沒有辦法傳入這個說明參數, 所以即使是無條件的狀態轉換,推薦增加一個恒成立的守衛 condition,以便能加上這個說明參數。

      示例代碼

      using System.Runtime.CompilerServices;
      using Stateless;
      
      namespace ConsoleApp1
      {
          internal class Program
          {
              private static void Main(string[] args)
              {
                  // Console.WriteLine("==================");
                  // Order goodsOrder = new Order(OrderState.Created);
                  // goodsOrder.isVirtualOrder = false;
                  // goodsOrder.pay("OpeatorA");
      
                  // Console.WriteLine("==================");
                  // Order virtualOrder = new Order(OrderState.Created);
                  // virtualOrder.isVirtualOrder = true;
                  // virtualOrder.pay("OpeatorB");
      
                  // Console.WriteLine("==================");
                  // Order paidOrder = new Order(OrderState.Paid);
                  // paidOrder.ship();
      
                  // Console.WriteLine("==================");
                  // Order shippedOrder = new Order(OrderState.Shipped);
                  // shippedOrder.ship();
      
      
                  //導出 graphviz 流程圖(.dot文件)
                  //最好使用綁定狀態機最開始的state對象來導出,這樣流程圖看起來更加漂亮, 當然也可以任意狀態的狀態機導出。
                  // Console.WriteLine("==================");
                  // Order oneOrder = new Order(OrderState.Created);
                  // Console.WriteLine(oneOrder.exportToGraphviz());
      
                  //導出 mermaid 流程圖
                  //最好使用綁定狀態機最開始的state對象來導出,這樣流程圖看起來更加漂亮, 當然也可以任意狀態的狀態機導出。
                  Console.WriteLine("==================");
                  Order oneOrder2 = new Order(OrderState.Shipped);
                  Console.WriteLine(oneOrder2.exportToMermaid());
              }
          }
      
          public class Order
          {
              public bool isVirtualOrder { get; set; }
      
              private string _operatorName;
      
              /// <summary>
              /// 狀態機對象應該從屬于業務對象
              /// </summary>
              private StateMachine<OrderState, OrderTrigger> _stateMachine;
      
              /// <summary>
              /// 聲明一個帶參數的trigger
              /// 狀態機只允許為一個trigger 枚舉值綁定一個帶參數的trigger
              /// </summary>
              private StateMachine<OrderState, OrderTrigger>.TriggerWithParameters<string> _payTrigger;
      
              public Order(OrderState orderState)
              {
                  // 初始化狀態機對象
                  // 需要指定狀態機的 initialState, 需要注意的是, 它并不是一定是整個流程中最開始的狀態, 而是本業務對象的當前狀態
                  _stateMachine = new StateMachine<OrderState, OrderTrigger>(orderState);
      
                  _stateMachine.OnTransitionCompleted(
                      (transition) => { Console.WriteLine($"Source:{transition.Source} Destination:{transition.Destination}"); }
                      );
      
                  //非傳參trigger,直接使用 trigger enum 即可
                  //傳參trigger, 必須聲明為 TriggerWithParameters 類型, 參數需要通過 Fire() 函數傳入, 需要在“目標State”的Configuration下通過 OnEntryFrom() 來接收參數
                  _payTrigger = _stateMachine.SetTriggerParameters<string>(OrderTrigger.Pay);
      
                  //演示使用守衛條件guard condition的狀態轉換,PermitIf()中的條件應該是互斥的.
                  //最好要為守衛條件設置一個描述信息,這個描述信息將會體現到導出流程圖的transition label上
                  _stateMachine.Configure(OrderState.Created)
                      .PermitIf(OrderTrigger.Pay, OrderState.Paid, () => { return isVirtualOrder == false; }, "Non virtual order")
                      .PermitIf(OrderTrigger.Pay, OrderState.Shipped, () => { return isVirtualOrder == true; }, "Virtual order");
      
                  _stateMachine.Configure(OrderState.Paid)
                      //用來接收Trigger傳參的OnEntryFrom()調用, 要放到“目標State”的Configuration下
                      .OnEntryFrom(_payTrigger, operatorName => { _operatorName = operatorName; Console.WriteLine($"{_operatorName}"); })
                      .Permit(OrderTrigger.Ship, OrderState.Shipped);
      
                  _stateMachine.Configure(OrderState.Shipped)
                      .Permit(OrderTrigger.Confirm, OrderState.Closed);
              }
      
              public void pay(string operatorName)
              {
                  Console.WriteLine(_stateMachine.State);
                  _stateMachine.Fire(_payTrigger, operatorName);
                  Console.WriteLine(_stateMachine.State);
              }
      
              public void ship()
              {
                  if (_stateMachine.CanFire(OrderTrigger.Ship))
                  {
                      Console.WriteLine(_stateMachine.State);
                      _stateMachine.Fire(OrderTrigger.Ship);
                      Console.WriteLine(_stateMachine.State);
                  }
                  else
                  {
                      Console.WriteLine($"Cannot fire {OrderTrigger.Ship} in state {_stateMachine.State}");
                  }
              }
      
              /// <summary>
              ///導出 graphviz 流程圖(.dot文件), 可以使用 VS code的  Graphviz Interactive Preview 插件預覽.dot 文件流程圖
              ///最好使用綁定狀態機最開始的state對象來導出,這樣流程圖看起來更加漂亮, 當然也可以任意狀態的狀態機導出。
              /// </summary>
              /// <returns></returns>
              public string exportToGraphviz()
              {
                  return Stateless.Graph.UmlDotGraph.Format(_stateMachine.GetInfo());
              }
      
              /// <summary>
              /// 將輸出內容加到 markdown 的 code block 中, 形式為:
              /// ```mermaid      流程內容   ```
              /// VS code 可以安裝 Markdown Preview Mermaid Support進行預覽, 或者通過網站 https://mermaid.live/ 瀏覽
              /// </summary>
              /// <returns></returns>
              public string exportToMermaid()
              {
                  return Stateless.Graph.MermaidGraph.Format(_stateMachine.GetInfo());
              }
          }
      
          public enum OrderState
          { Created, Paid, Shipped, Closed }
      
          public enum OrderTrigger
          { Pay, Ship, Confirm }
      }
      

      輸出的graphviz流程圖:
      輸出的graphviz流程圖

      輸出的mermaid流程圖:
      輸出的mermaid流程圖

      posted @ 2025-11-05 07:38  harrychinese  閱讀(7)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 欧美交a欧美精品喷水| 成人午夜大片免费看爽爽爽| 男女男免费视频网站国产| 久久99精品久久久久久| 综合图区亚洲另类偷窥| 国产精品成人一区二区三区| 亚洲av激情综合在线| 国产在线精品福利91香蕉| 国产av黄色一区二区三区| 亚洲少妇人妻无码视频| 久久天堂无码av网站| 精品人妻av中文字幕乱| 在线天堂中文www官网| 国产精品自拍视频第一页| 亚洲最大成人av免费看| 精品91在线| 国产色婷婷亚洲99精品小说| 高清有码国产一区二区| aaa少妇高潮大片免费看| 国产精品麻豆欧美日韩ww| 不卡国产一区二区三区| 一边吃奶一边摸做爽视频| 国产91精品一区二区蜜臀| 肉大捧一进一出免费视频| 亚洲精品乱码久久久久久| 国产一区二区精品偷系列| 国产中文成人精品久久久| 馆陶县| 人人澡人人透人人爽| FC2免费人成在线视频| 国内精品久久久久影院网站| 亚洲人精品午夜射精日韩| 久久人人97超碰精品| 新津县| 国产熟女高潮一区二区三区| 精品国精品自拍自在线| 94人妻少妇偷人精品| 亚洲18禁一区二区三区| 亚洲aⅴ男人的天堂在线观看| 亚洲精品乱码久久观看网| 亚洲欧洲日韩国内高清|