ナレッジNEW
【連載】概念モデリングを習得しよう:生成・消滅型と巡回型の状態モデル、イベント駆動による振舞いの考え方(第22回)

【前回の連載記事はこちら】
【連載】概念モデリングを習得しよう:状態モデルの作り方とUML図法の使い分け、概念モデリング実践のポイント(第21回)
読者の皆さん、こんにちは。Knowledge & Experience 代表の太田 寛です。この連載コラムでは概念モデリングについて解説しています。
今回は、状態モデルを実践的に活用するための基本パターンとして、「生成・消滅型」と「巡回型」の二つを解説します。あわせて、is-aのリレーションシップでつながる概念クラス群の状態モデルの考え方や、アクションを構成するプロセス、イベント生起によって並行動作する状態機械の振舞いについて、果樹園のドメインを題材に整理します。
状態モデルのパターン
これまで解説してきた考え方で、意味の場を通じて観察した事柄の振舞いの構造を、概念クラスの状態モデルとして記述すると、幾つかバリエーションはあるものの、以下に挙げる二つのパターンの状態モデルになっていきます。
- 生成・消滅型
- 巡回型
生成・消滅型は、概念インスタンスが作成された後、この概念インスタンスへのイベント生起に応じて状態遷移を行い、最終的には削除されるものです。
果樹園の概念モデルでは、“栽培中のリンゴ”がそれに相当します。現実世界において、何かが生まれ出でて、何らかの出来事により変化して、最終的に消えていく様相の写しです。
巡回型は、果樹園の概念モデルでは、樹木や収穫リソースなど、それぞれの概念インスタンスは存在し続け、イベントの生起に従って同じサイクルの状態遷移を繰り返すものです。
筆者の30年来の経験から、それぞれの概念クラスに相当する意味を細かく定義しながら、概念情報モデルの粒度を細かくしていくと、最終的には、この二つのパターンの状態モデルだけになっていくことが分かっています。UMLの状態マシン図のような複雑な状態モデルを記述できることに慣れた技術者には、このシンプルさが物足りなく感じるかもしれません。しかし、記述した状態モデルを検証する時には、シンプルさはとても重要です。このトピックについては後程詳しく解説する予定です。
果樹園の概念情報モデルのうち、R1のリレーションシップに関連する概念クラス群だけを切り出してみます。果樹園の概念情報モデルではR1という“is-a”のリレーションシップで、“リンゴ”と“栽培中のリンゴ”、“収穫済みのリンゴ”、“試食用リンゴ”がつながっていました。このような概念情報モデルの場合、“is-a”につながったどの概念クラスに対しても、それぞれの状態モデルの定義が可能です。
スーパー側の概念クラスの状態モデルは、全般の振舞いを記述し、サブ側の概念クラスの状態モデルは、それぞれの事情にかかわる振舞いを記述することになります。
以前の回で、is-aのリレーションシップには、マイグレーションと分類があると解説しました。is-aのリレーションシップでつながる概念クラスが状態モデルを持つ場合、次のようになるのが一般的です。
- マイグレーション
▶ スーパー側の概念クラスの状態モデルは、ライフサイクル全体の振舞いを記述する
▶ サブ側の概念クラス群のそれぞれの状態モデルは、
それぞれのライフサイクルのステージごとの詳細の振舞いを記述する - 分類
▶ スーパー側の概念クラスの状態モデルは、分類に共通する振舞いを記述する
▶ サブ側の概念クラス群のそれぞれの状態モデルは、それぞれの詳細な振舞いを記述する
状態モデルを記述している時に、これらの特徴に当てはまらないようなら、その is-aのリレーションシップが妥当なのか見直してみましょう。
オブジェクト指向プログラミングに慣れた読者の中には、スーパー側の概念クラスを、いわゆる抽象クラス(abstract class)と混同してしまう人がいるかもしれません。本コラムでは詳しく触れませんが、is-a のリレーションシップでつながった概念クラスの状態モデルの煩雑さを解消するために、多態事象(Polymorphic Event)という道具立ても用意されています。抽象クラスと見かけ上似ていないこともないのですが、オブジェクト指向プログラミングの諸概念は一切忘れて取り組むこと、それが、概念モデリング習得の早道です。
アクションを構成するプロセスの分類
アクションを構成するプロセスの分類は、ドメインファンクションの解説でも一覧で紹介しましたが、イベント生起が追加されているので、ここに再掲しておきます。
- 概念クラスのインスタンスの選択
▶ SELECT ~ FROM INSTANCES OF class [ WHERE ~ ] ;
▶ その時点で、存在する全ての概念インスタンスを参照可能とする - リレーションシップをたどってリンクされた概念インスタンスの選択
▶ SELECT ~ RELATED BY ~ [ WHERE ~ ] ; - 概念インスタンスの特徴値への参照
▶ instance.property - 概念インスタンスの特徴値の更新
▶ instance.property = value ;
▶ ただし、識別子、参照、算術演算を表す特徴値の更新は不可 - 概念クラスを指定した、概念インスタンスの作成
▶ CREATE OJBECT INSTANCE instance of class ; - 概念インスタンスの削除
▶ DELETE OBJECT INSTNACE instance ; - リレーションシップを指定した、概念インスタンス間のリンクを作成
▶ RELATE a TO b ACROSS Rn [ USING c ] ;
▶ リンク作成とともに参照特徴値が更新される - リレーションシップを指定した、概念インスタンス間のリンクの削除
▶ UNRELATE a FROM b ACROSS Rn [ USING c ] ;
▶ リンク削除とともに参照特徴値が更新される - 算術計算
▶ v0 [+|-|*|/|%] v1 - 論理計算
▶ l0 [AND|OR|==|!=|>|>=|<|<=] l1
▶ NOT l - 概念インスタンス集合の要素数
▶ CARDINALITY instanceSet - 概念クラスにひも付いたオペレーション
▶ instance.operation() - 外部実体のファンクション
▶ EE::function() - イベントの生起
▶ GENERATE EL:Meaning([supname:value,…] TO [ SELF | instance |C CREATOR] ;
現実世界の様相がそうであるように、圏Iのモデル上では複数の状態機械が同時並行的に動いています。
ある状態機械がイベントを消費し、遷移先のエントリーアクションを実行している間、それとは無関係に、エントリーアクションを実行している別の状態機械が複数あることに、留意が必要です。
状態モデルの実行セマンティクス
ドメインファンクションの説明で、アクションはデータフローモデルであり、データフローモデルの実行セマンティクスに従ってプロセスの実行が行われると解説しました。ここでは、状態モデルの実行セマンティクスを、図表を交えて定義しておきます。実行セマンティクスが明確に定義されていれば、誰かが描いた状態モデルが実際どうふるまうのか、誰が試してみても、同じ振舞いになることが保証されるからです。
逆に、明確な実行セマンティクスが無ければ、たとえ同じ状態モデルを対象としていても、人によって解釈が異なってしまい、せっかく苦労して描いた状態モデル群も絵にかいた餅で終わってしまいます。
以下に、生起されたイベントのルールを列記します。
- ある状態機械に対して、異なる状態機械、および、概念ドメインの埒外が生起したイベントの消費順は不定である
▶ 二つイベントが生起された場合、
どちらのイベントを先に受け取っても妥当な遷移が行われるような状態モデルであること - ある状態機械が、別の状態機械に対して二つ以上のイベントを生起した場合、消費する側の状態機械は、生起順にイベントが消費される
- ある状態機械が、自分自身に対してイベントを生起した場合、そのイベントが最初に消費される
- 生起されたイベントが状態機械に消費されるまでには有限の時間がかかる
これらは現実の世界の様相をもとに決められたルール群です。例として挙げている果樹園のモデルだけでなく、日常業務における各種やりとり、制御システムにおける連携など想像してみれば、これらのルールの妥当性が腑に落ちることでしょう。
前述の通り、生起されたイベントに対し、ある状態機械の遷移が生じ、遷移先の状態のエントリーアクションが実行されます。その際、そのエントリーアクションを構成する全プロセスは、データフローモデルの実行セマンティクスに従って、それぞれの入力データがそろった時点で同時並行的に実行されていきます。
エントリーアクションにひも付く全てのプロセスが実行されて状態の遷移が確定するまでの状態を、中間状態(イミディエイトステート)と呼びます。エントリーアクションを構成する、それぞれのプロセスが同時並行的に実行されるというルールにより、中間状態では、概念情報モデルで記述されたプロパティ値の確定や、リレーションシップの多重度に関する制約が破られてしまう状況がどうしても生じてしまいます。このため、全プロセスの実行が完了した時点、すなわち、状態遷移が確定した時点では、概念情報モデルの制約が満たされていなければなりません。
繰り返しになりますが、現実の世界ではそこかしこで出来事が起こり、同時並行的に物事が進行していきます。現実世界の写しである圏Iでは、複数の状態機械がそれぞれのイベントの生起に応じて動いていることを考慮しモデリングしなければなりません。ある状態機械のエントリーアクションにおいて参照している意味的リンクや概念インスタンスが、別の状態機械のエントリーアクションで削除されているかもしれません。そのような状況を考慮せずに状態モデルを作成していると、全体を俯瞰したときに概念情報モデルによる制約が満たさない状況が生じてしまうかもしれないのです。
現状のビジネスや制御の状況を可視化したものが概念モデルです。次に解説するシミュレーションにより、概念情報モデルで定義された各種制約が満たされないような振舞いを見つける場合があります。これは、何か重要な事実を見落とすことにより、作成したモデルが間違ったか、現状に潜んでいた問題点を発見したかのどちらかです。
こんな時は関係者を集めて、作成したモデルが、意味の場を通じて観察している対象を正しく記述しているかを吟味してください。正しく記述しているにもかかわらず、概念情報モデルの制約が満たされない状況が生じているならば、実際の世界で何らかの論理的破綻が生じる可能性があることを示唆しています。概念情報モデルと状態モデル群を使うことにより、現状の問題が発見でき、モデルを修正しながら、その解決策を探ることができるのです。
状態モデルについては、“Art of Conceptual Modeling 4. 概念振舞いモデル”で詳しく解説しています。このコラムもぜひご一読ください。
概念モデリングでは、エントリーアクションも含めた状態モデルとドメインファンクションをまとめて、概念振舞いモデルと呼ぶことにしています。
概念モデルによるシミュレーション
概念情報モデルを基に、現実世界の写しである圏Iのモデルを構成し、イベントを生起すれば、状態モデルに従った圏Iのモデルの変化が生じます。その変化を観察することにより、現実世界のシミュレーションを行えます。
より厳密に言えば、概念モデルを使って次のような事柄を実行することがシミュレーションに相当します。
- 現実世界に対応する圏Iのモデルを構成する
▶ ドメインファンクションによるアクション記述と実行
▷ 存在する概念インスタンスの生成
▷ 概念インスタンスの特徴値の値の設定
▷ 概念インスタンス間の意味的リングの作成 - イベントの生起
▶ 概念インスタンスを生成するイベントの場合
▷ 状態モデルをひな型として、一つの状態機械を作成する
▷ 生成イベントがひも付いた遷移先の状態のエントリーアクションを実行する▶ 既存の概念インスタンスに対するイベントの場合
▷ その状態機械の現在状態から遷移先の状態を見つける▷ 遷移先の状態のエントリーアクションを実行する
- 圏Iのモデルを観察する
▶ 観察したい事項を参照するドメインアクション記述と実行
▷ 概念インスタンスの生成・消滅
▷ 概念インスタンスの特徴値の変化
▷ 意味的リンクの作成・削除
シミュレーションは、概念情報モデル図と全ての状態モデル図、大きめのホワイトボード、マーカー、ポストイットなどを使うことにより、以下の手順で、人手で実践できます。
- 初期状態で作成する概念インスタンスそれぞれに対し、(ア)~(エ)を行う
(ア) ポストイットに概念クラスの名前と識別子特徴値の値を書き込んでホワイトボードに張る
(イ) リレーションシップをひな型にした意味的なリンクを、ポストイットをつなぐ線として書き込み、リレーションシップの名前を付与する
(ウ) 状態モデルが定義されている場合は、そのモデル図のコピーを一枚作成し、識別子特徴値の値を書き込むとともに、初期の状態にマーカーを置く
(エ) 概念クラスの特徴値をカラムとした表(“概念インスタンス表”)を作成し、概念インスタンス毎に行を作成して、全ての特徴値の値を書き込む
- 生起するイベントごとに、(ア)を行う
(ア) ポストイットに、そのイベントラベルと、消費先の概念インスタンスの識別子特徴値の値と引数の値を書きこみ、ホワイトボードに貼る
- 張られたポストイット、それぞれに対して、(ア)~(オ)を行う
(ア) ホワイトボードからはがして、消費する概念インスタンスの状態モデル図のコピーを探し、遷移先の状態を特定し、マーカーをその遷移線に移動する
(イ) 遷移先の状態のエントリーアクションを実行し、
① ホワイトボード上の概念インスタンスの特徴値・リンクを更新する
② 生成されたイベントを示すポストイットを作成し、ホワイトボードに貼る
(ウ) 更新された特徴値の値で、対応する概念インスタンス表の値を更新する
(エ) エントリーアクション実行完了時点で、マーカーを遷移先の状態に移動する
(オ) 遷移先の状態が最終状態の場合は、対応する概念インスタンスのポストイットをはがし、それにひも付いた特徴値・リンクを消すとともに、対応する状態モデル図のコピーを破棄する
- 2.~3.の実施経過を(ア)、(イ)、(ウ)に対して観察・記録する
(ア) 生成されたイベント
(イ) 概念インスタンス表の行、セルの更新履歴
(ウ) 概念情報モデルで定義された制約を満たしているか確認
① リレーションシップの多重度
② 特徴値の値制約
シミュレーションは複数人で実施するのが良いでしょう。その際、前記した2と3を同時並行で行うことにより、現実世界に忠実なシミュレーションが可能です。
実際やってみると、人手によるシミュレーションは、非常に手間のかかるタフな作業です。
概念モデリングの基であるShlaer-Mellor法専用ツールのBridgePointにはModel Verifierというツールが用意されています。このツールを用いればシミュレーション実行に伴う苦痛を幾ばくか和らげてくれるでしょう。
繰り返しになりますが、概念モデルは、意味の場を通じて認識した現実世界の写しのスキーマです。それゆえ、概念モデルを使ったシミュレーションでは、その実行中の圏Iのモデルの変化が、現実世界の様相と齟齬がなく、忠実な写しになっていなければなりません。これが、作成した概念モデルが妥当であることを示す唯一の指標だからです。
シミュレーションの実行は、作成したモデルの動的な側面の妥当性を検証(Verify)することと同義であるといえます。BridgePointで提供されているシミュレーション用のツールの名前が、Model Simulatorではなく、Model Verifierになっていることにはこれに由来しています。
余談になりますが、シミュレーション中の、概念インスタンス間で生じたイベントの、送受信の時系列的な流れの図示は、UMLの相互作用図が利用できます。また、その流れの中で実行されたアクションやプロセスの時系列的な関係を図示したい場合は、UMLのアクティビティ図を利用するとよいでしょう。なお、これらの様相を図にする際、それらの図は、圏Cをひな型とした 圏Iの世界の描写であることに留意してください。これら圏Iの図は、シミュレーションの条件をちょっとだけ変えるだけで、大きく変化してしまうからです。
モデリングでは、ひな型の圏Cのモデリングに注力し、それから導出可能な圏Iのモデル図は変化しやすいので、作成することは必要最低限にとどめ、無駄な労力をかけないようにしましょう。
次回は、概念モデルのシミュレーションを通じて、リソース競合などのビジネス上の問題をどのように発見し、解決策へつなげていくのかを、果樹園のドメインを題材に解説します。
この記事は面白かったですか?
今後の改善の参考にさせていただきます!





























































-portrait.webp)





























