2021年9月30日木曜日

Kaleidox状態機械/エンティティ

前回はリソースに対するイベントに対して反応する状態機械を定義し、Kaleidox上で動作させました。

今回はこの機能を拡張してエンティティ・オブジェクトの状態機械を定義してみます。

モデル

今回のモデルはエンティティsalesorderを定義し、そのプロパティとして状態機械statusを定義しています。

状態機械statusは前回定義したpurchaseと同じものです。

この設定を行ったエンティティの定義は以下になります。

  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. *** statemachines  
  24. **** status  
  25. state=[{  
  26.   name=INIT  
  27.   transition=[{  
  28.     to=running  
  29.   }]  
  30. },{  
  31.   name=canceled  
  32.   transition=[{  
  33.     to=FINAL  
  34.   }]  
  35. },{  
  36.   name=suspended  
  37.   transition=[{  
  38.     guard=resume  
  39.     to=HISTORY  
  40.   }]  
  41. }]  
  42. statemachine=[{  
  43.   name="running"  
  44.   state=[{  
  45.     name=applying  
  46.     transition=[{  
  47.       to=confirming  
  48.     }]  
  49.   },{  
  50.     name=confirming  
  51.     transition=[{  
  52.       guard=confirm  
  53.       to=confirmed  
  54.     },{  
  55.       guard=reject  
  56.       to=rejected  
  57.     }]  
  58.   },{  
  59.     name=confirmed  
  60.     transition=[{  
  61.       to=delivering  
  62.     }]  
  63.   },{  
  64.     name=rejected  
  65.     transition=[{  
  66.       to=FINAL  
  67.     }]  
  68.   },{  
  69.    name=delivering  
  70.     transition=[{  
  71.       guard=delivered  
  72.       to=delivered  
  73.     }]  
  74.   },{  
  75.     name=delivered  
  76.     transition=[{  
  77.       to=FINAL  
  78.     }]  
  79.   }]  
  80.   transition=[{  
  81.     guard=cancel  
  82.     to=canceled  
  83.   },{  
  84.     guard=suspend  
  85.     to=suspended  
  86.   }]  
  87. }]  

イベント

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

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

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

エンティティ

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

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

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

状態機械statusは、前回作成した状態機械purchaseのstate部分を使用しています。

前回の定義にある以下の部分は:

  1. name="purchase"  
  2. kind=resource  

それぞれ以下のようになっています。

  • 状態機械名は定義していません。
  • kindはエンティティのプロパティなのでresourceに設定されます。

状態機械

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

実行

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

まず最初にentity-create関数でエンティティを生成します。第1引数にエンティティ名、第2引数にエンティティ作成時のパラメタを指定します。今回はパラメタがないのでnilを指定しています。

生成したエンティティのIDは「3mRehDtuMYmTO0gpzCcaDa」、エンティティの状態機械statusの状態はconfirmingになっています。

  1. kaleidox> entity-create 'salesorder nil  
  2. Entity[3mRehDtuMYmTO0gpzCcaDa;status:confirming]  
  3. kaleidox> setq o  
  4. Entity[3mRehDtuMYmTO0gpzCcaDa;status:confirming]  

ここでevent-issue関数でconfirmイベントを送出します。

前回と同様に状態機械はevent-issue関数で発行されたイベントには無反応です。

  1. kaleidox> event-issue 'confirm  
  2. Event[confirm]  
  3. kaleidox> o  
  4. Entity[4WVhMPHFzEJQCqUFpSxN3r;status:confirming]  

リソースに関連付けられた状態機械へのイベント送出にはevent-call関数を用います。第1引数にイベント名、第2引数にイベント送信先のリソースID「12340」を指定しました。

この場合は、先ほど作成した状態機械には変化がありません。

  1. kaleidox> event-call 'confirm "12340"  
  2. Event[confirm]  
  3. kaleidox> o  
  4. Entity[4WVhMPHFzEJQCqUFpSxN3r;status:confirming]  

次に第1引数にイベント名、第2引数にイベント送信先のリソースID「3mRehDtuMYmTO0gpzCcaDa」を指定しました。リソースID「3mRehDtuMYmTO0gpzCcaDa」は先程作成した状態機械に関連付けられたものです。

今回は、エンティティの状態機械の状態が無事confirmingからdeliveringに変わりました。

  1. kaleidox> event-call 'confirm "3mRehDtuMYmTO0gpzCcaDa"  
  2. Event[confirm]  
  3. kaleidox> o  
  4. Entity[4WVhMPHFzEJQCqUFpSxN3r;status:delivering]  

まとめ

今回は状態機械を持ったエンティティを作成し、エンティティのID指定で状態機械を駆動させてみました。

オブジェクト・モデルの動的モデルはオブジェクトに包含された状態機械によって実現するのがセオリーですが、一般的なオブジェクト指向言語では状態機械はサポートされていないので、実装はそれなりの手間が必要でした。

この距離を埋める解決策はモデル駆動開発です。定義したモデルを直接実行することができれば、この問題が発生することはありません。その一実例としてKaleidoxでのエンティティ&状態機械のモデル定義と実行の様子をご紹介しました。

次回は状態機械にアクションを登録して、エンティティの振る舞いを定義してみます。

諸元

Kaleidox
0.3.2