2021年11月30日火曜日

Kaleidox状態機械/エンティティの状態遷移

前回は状態機械を持ったエンティティをデータベースに格納、管理してみました。

今回は状態機械を持ったエンティティを状態遷移させてみます。

モデル

々回、前回とエンティティsalesorderを定義し状態機械の設定も行いました。

今回もこの定義をそのまま使います。

  1. * event  
  2. event=[{  
  3.     name="confirm"  
  4.   },{  
  5.     name="reject"  
  6.   },{  
  7.     name="delivered"  
  8.   },{  
  9.     name="cancel"  
  10.   },{  
  11.     name="suspend"  
  12.   },{  
  13.     name="resume"  
  14. }]  
  15. * entity  
  16. ** salesorder  
  17. *** features  
  18. table=salesorder  
  19. *** attributes  
  20. | Name  | Type  | Multiplicity |  
  21. |-------+-------+--------------|  
  22. | id    | token |            1 |  
  23. | price | int   |            1 |  
  24. *** statemachines  
  25. **** status  
  26. state=[{  
  27.   name=INIT  
  28.   transition=[{  
  29.     to=running  
  30.   }]  
  31. },{  
  32.   name=canceled  
  33.   transition=[{  
  34.     to=FINAL  
  35.   }]  
  36. },{  
  37.   name=suspended  
  38.   transition=[{  
  39.     guard=resume  
  40.     to=HISTORY  
  41.   }]  
  42. }]  
  43. statemachine=[{  
  44.   name="running"  
  45.   state=[{  
  46.     name=applying  
  47.     transition=[{  
  48.       to=confirming  
  49.     }]  
  50.   },{  
  51.     name=confirming  
  52.     transition=[{  
  53.       guard=confirm  
  54.       to=confirmed  
  55.     },{  
  56.       guard=reject  
  57.       to=rejected  
  58.     }]  
  59.   },{  
  60.     name=confirmed  
  61.     transition=[{  
  62.       to=delivering  
  63.     }]  
  64.   },{  
  65.     name=rejected  
  66.     transition=[{  
  67.       to=FINAL  
  68.     }]  
  69.   },{  
  70.    name=delivering  
  71.     transition=[{  
  72.       guard=delivered  
  73.       to=delivered  
  74.     }]  
  75.   },{  
  76.     name=delivered  
  77.     transition=[{  
  78.       to=FINAL  
  79.     }]  
  80.   }]  
  81.   transition=[{  
  82.     guard=cancel  
  83.     to=canceled  
  84.   },{  
  85.     guard=suspend  
  86.     to=suspended  
  87.   }]  
  88. }]  

イベント

以下の6つのイベントを定義しています。

confirm
確認OK
reject
確認却下
delivered
配送済み
cancel
キャンセル
suspend
保留
resume
再開

前回からの変更点はありません。

エンティティ

エンティティの定義も前回から変更点はありません。

entity節の下にエンティティ「salesorder」を定義しています。

エンティティ「salesorder」の下にfeatures節で特性、attributes節で属性、statemachines節で状態機械を定義しています。

statemachines節の下に状態機械「status」を定義しています。

状態機械

定義したモデルの状態機械図は前回と同じ以下となります。

実行

それでは実行してみましょう。

準備

まず、前回記事までのおさらいです。

前回の記事でデータベース上に状態機械を持ったsalesorderオブジェクトを作成しました。手順を再現すると以下になります。

entity-create-collection関数でエンティティを格納するコレクションを作成します。コレクションのバックエンドはデータベースのテーブルになります。

  1. kaleidox> entity-create-collection 'salesorder  
  2. true  

次にentity-create関数でエンティティを作成します。

状態機械statusの状態はconfirmingになっています。

  1. kaleidox> entity-create 'salesorder price=100  
  2. id:qXj7DyqEdu7rosSNdQ9R7;price:100;status:confirming  
  3. kaleidox> :show:pretty  
  4. ┏━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━┓  
  5. ┃Name  │Value                 ┃  
  6. ┣━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━┫  
  7. ┃id    │qXj7DyqEdu7rosSNdQ9R7 ┃  
  8. ┃price │100                   ┃  
  9. ┃status│confirming            ┃  
  10. ┗━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━┛  

salesorderエンティティのデータベースでの格納状況を確認するためにstore-get関数でデータベースから直接データを取得してみます。

  1. kaleidox> store-get 'salesorder "qXj7DyqEdu7rosSNdQ9R7"  
  2. ID:qXj7DyqEdu7rosSNdQ9R7;PRICE:100;STATUS:501  
  3. kaleidox> :show:pretty  
  4. ┏━━━━━━┯━━━━━━━━━━━━━━━━━━━━━┓  
  5. ┃Name  │Value                ┃  
  6. ┣━━━━━━┿━━━━━━━━━━━━━━━━━━━━━┫  
  7. ┃ID    │qXj7DyqEdu7rosSNdQ9R7┃  
  8. ┃PRICE │100                  ┃  
  9. ┃STATUS│201                  ┃  
  10. ┗━━━━━━┷━━━━━━━━━━━━━━━━━━━━━┛  

STATUSカラムには、状態confirmingに対応する数値201が格納されていることが確認できました。

エベントの送出

event-call関数でCALLイベントconfirmをsalesorderエンティティ「qXj7DyqEdu7rosSNdQ9R7」に対して送出します。

  1. kaleidox> event-call :entity 'salesorder 'confirm "qXj7DyqEdu7rosSNdQ9R7"  
  2. Event[confirm]  

状態遷移の確認

confirmイベントを受信したsalesorderエンティティの状態をentity-get関数で確認します。

状態機械statusが状態confirmingから状態deliveringに遷移していることを確認できました。

  1. kaleidox> entity-get 'salesorder "qXj7DyqEdu7rosSNdQ9R7"  
  2. id:salesorder-qXj7DyqEdu7rosSNdQ9R7;price:100;status:delivering  
  3. kaleidox> :show:pretty  
  4. ┏━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━┓  
  5. ┃Name  │Value                 ┃  
  6. ┣━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━┫  
  7. ┃id    │qXj7DyqEdu7rosSNdQ9R7 ┃  
  8. ┃price │100                   ┃  
  9. ┃status│delivering            ┃  
  10. ┗━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━┛  

salesorderエンティティのデータベースでの格納状況を確認するためにstore-get関数でデータベースから直接データを取得してみます。

  1. kaleidox> store-get 'salesorder "qXj7DyqEdu7rosSNdQ9R7"  
  2. ID:qXj7DyqEdu7rosSNdQ9R7;PRICE:100;STATUS:501  
  3. kaleidox> :show:pretty  
  4. ┏━━━━━━┯━━━━━━━━━━━━━━━━━━━━━┓  
  5. ┃Name  │Value                ┃  
  6. ┣━━━━━━┿━━━━━━━━━━━━━━━━━━━━━┫  
  7. ┃ID    │qXj7DyqEdu7rosSNdQ9R7┃  
  8. ┃PRICE │100                  ┃  
  9. ┃STATUS│501                  ┃  
  10. ┗━━━━━━┷━━━━━━━━━━━━━━━━━━━━━┛  

STATUSカラムには、状態deliveringに対応する数値501が格納されていることが確認できました。

まとめ

今回はデータベース上に永続化されているエンティティに対してイベント送出によって状態遷移を起こし、その状態遷移がデータベース上に反映されていることを確認することができました。

永続オブジェクトであるエンティティの状態機械は、永続オブジェクトの読込みと書き戻しの処理が伴うので、プログラムで実装するのは少し手間がかかります。この手間をモデル駆動開発によって削減でできることが分かりました。

次回は状態機械のアクションについてみていきます。

諸元

Kaleidox
0.3.4