2021年11月30日火曜日

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

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

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

モデル

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

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

* event
event=[{
    name="confirm"
  },{
    name="reject"
  },{
    name="delivered"
  },{
    name="cancel"
  },{
    name="suspend"
  },{
    name="resume"
}]
* entity
** salesorder
*** features
table=salesorder
*** attributes
| Name  | Type  | Multiplicity |
|-------+-------+--------------|
| id    | token |            1 |
| price | int   |            1 |
*** statemachines
**** status
state=[{
  name=INIT
  transition=[{
    to=running
  }]
},{
  name=canceled
  transition=[{
    to=FINAL
  }]
},{
  name=suspended
  transition=[{
    guard=resume
    to=HISTORY
  }]
}]
statemachine=[{
  name="running"
  state=[{
    name=applying
    transition=[{
      to=confirming
    }]
  },{
    name=confirming
    transition=[{
      guard=confirm
      to=confirmed
    },{
      guard=reject
      to=rejected
    }]
  },{
    name=confirmed
    transition=[{
      to=delivering
    }]
  },{
    name=rejected
    transition=[{
      to=FINAL
    }]
  },{
   name=delivering
    transition=[{
      guard=delivered
      to=delivered
    }]
  },{
    name=delivered
    transition=[{
      to=FINAL
    }]
  }]
  transition=[{
    guard=cancel
    to=canceled
  },{
    guard=suspend
    to=suspended
  }]
}]

イベント

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

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

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

エンティティ

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

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

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

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

状態機械

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

実行

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

準備

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

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

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

kaleidox> entity-create-collection 'salesorder
true

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

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

kaleidox> entity-create 'salesorder price=100
id:qXj7DyqEdu7rosSNdQ9R7;price:100;status:confirming
kaleidox> :show:pretty
┏━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━┓
┃Name  │Value                 ┃
┣━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━┫
┃id    │qXj7DyqEdu7rosSNdQ9R7 ┃
┃price │100                   ┃
┃status│confirming            ┃
┗━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━┛

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

kaleidox> store-get 'salesorder "qXj7DyqEdu7rosSNdQ9R7"
ID:qXj7DyqEdu7rosSNdQ9R7;PRICE:100;STATUS:501
kaleidox> :show:pretty
┏━━━━━━┯━━━━━━━━━━━━━━━━━━━━━┓
┃Name  │Value                ┃
┣━━━━━━┿━━━━━━━━━━━━━━━━━━━━━┫
┃ID    │qXj7DyqEdu7rosSNdQ9R7┃
┃PRICE │100                  ┃
┃STATUS│201                  ┃
┗━━━━━━┷━━━━━━━━━━━━━━━━━━━━━┛

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

エベントの送出

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

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

状態遷移の確認

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

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

kaleidox> entity-get 'salesorder "qXj7DyqEdu7rosSNdQ9R7"
id:salesorder-qXj7DyqEdu7rosSNdQ9R7;price:100;status:delivering
kaleidox> :show:pretty
┏━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━┓
┃Name  │Value                 ┃
┣━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━┫
┃id    │qXj7DyqEdu7rosSNdQ9R7 ┃
┃price │100                   ┃
┃status│delivering            ┃
┗━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━┛

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

kaleidox> store-get 'salesorder "qXj7DyqEdu7rosSNdQ9R7"
ID:qXj7DyqEdu7rosSNdQ9R7;PRICE:100;STATUS:501
kaleidox> :show:pretty
┏━━━━━━┯━━━━━━━━━━━━━━━━━━━━━┓
┃Name  │Value                ┃
┣━━━━━━┿━━━━━━━━━━━━━━━━━━━━━┫
┃ID    │qXj7DyqEdu7rosSNdQ9R7┃
┃PRICE │100                  ┃
┃STATUS│501                  ┃
┗━━━━━━┷━━━━━━━━━━━━━━━━━━━━━┛

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

まとめ

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

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

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

諸元

Kaleidox
0.3.4