見出し画像

4. 概念振舞モデル

本ドキュメントの利用は、https://github.com/kae-made/kae-made/blob/main/contents-license.md に記載のライセンスに従ってご利用ください。

https://github.com/kae-made/kae-made/blob/main/contents-license.md

Date:2023/11/25 - Version:1.1.1

概念モデリングにおける“振舞”は、モデル化対象ドメインの文脈において意味のある“事象”が発生した時の、概念情報モデルのインスタンス群とリンクの状態の、ビジネス要件に従った変化の様であり、それを一定のルールの元に図やテキストで記述したものが“概念振舞モデル”です。


振舞の基本

先ずは、概念振舞モデルの構築で使用する用語を定義していきます。
以下、シンプルな説明のために、「概念情報モデルのインスタンス群とリンクの状態」を“概念情報モデルの状態”、あるいは、単に“状態”という用語を使って説明をしていくことにします。

事象

”事象“は、モデル化対象ドメインの文脈において、ビジネス的に意味のある出来事を抽象化したものです。”事象“は一つ以上の値を伴う場合があります。
振舞いのモデリングにおいては、現実世界で発生する個々の”事象”と、それ等を抽出・整理した上での分類としての”事象”を区別するようにしましょう。前者と後者の関係は、丁度、概念情報モデルにおける、”概念インスタンス”と”概念クラス”の関係と同じです。このセクションでの”事象”は、抽出・整理した上での分類としての”事象”であるとご理解ください。

アクション

“概念情報モデルの状態を”変化させる処理の中身を“アクション”と呼びます。
“アクション”の定義に従って“状態”を変化させることを、“アクションを実行する”と呼びます。
“アクション”は、モデル化対象ドメインにおいて、“事象”が発生した時に行われるビジネスシナリオの一部に相当し、以下に示す操作の基本単位を組み合わせて構成されます。

  • 概念情報モデルに対する5種類の状態の更新

  • 概念情報モデルに対する3種類の問合せ

  • データ変換

  • 条件判定

  • 事象の発生

  • ドメインの外側の仕組みからのデータ取得

最初の二つは、「概念情報モデルの操作」の章を参照してもらうとして、他の基本単位について解説していきます。
データ変換”は、事象に付帯したデータやインスタンスの特徴値の値、及び、別の“データ変換”操作の結果をビジネス上の観点に従って変換する操作です。算術計算はこの分類に含まれます。
“条件判定”は、ビジネス上の判断基準を、事象に付帯したデータやインスタンスの特徴値の値、及び、別の“データ変換”操作の結果から生じたデータ群から、ある条件に合致するか(=True)、否か(=False)に変換するアクションです。
事象の発生”は、モデル化対象のドメイン、または、他のドメインで定義された状態モデルの“事象(イベント)”のインスタンスを発生する操作です。
ドメインの外側の仕組みからのデータ取得”は、ちょっと特殊な操作です。この操作については、本稿の最後で詳細を説明します。

一通りざっと大仰に紹介してきましたが、基本的には通常のプログラミング言語を使った処理の記述と同じだと思って構いません。ただし、違う点がいくつかあります。
まず、概念振舞モデルの“アクション”は、必ず、実行が完了しなければなりません。従って、


while (true) {
    …
}

の様な無限ループはありません。

次に、アクションで参照できる変数は、

  • 問合せ操作で取得したインスタンスの集合、及び、その集合に属する各インスタンスへの参照

  • 参照しているインスタンスの特徴値

  • 事象の引数

  • データ変換操作が生成したデータ

のみが使用できます。変数のデータ型が、概念モデルに想定されるアプリオリな基本データ型

  • 文字列

  • 整数

  • 実数

  • 真偽値

  • 概念インスタンス参照

  • 概念インスタンス集合

以外のものは、モデル作成者が、モデル化対象ドメインのコンテキストにおいて独自に定義した、ユーザー定義データ型でなければなりません。
由来の不明な参照や変数は使えず、意味のない 3.5 や 7 といった即値や固定の文字列も使えません。

また、操作の基本単位の実行は、全て実行可能な時に同時並行的に実行されると考えます。

データフローモデル

通常のプログラミング言語で書かれた処理の記述では大抵の場合、書かれた順番に行が実行されていきますが、“アクション”では、それぞれの基本操作単位は、それを実行するのに必要なデータが揃った時に実行開始するという、データフローモデルの処理の流れを実行の基本とします。

画像1
図1. データフローモデル

念のため、データフローモデルの定義と実行ルールをテキストでも列記しておきます。

データフローモデルの定義

  • データフローモデルは、プロセス)とデータの流れから構成される

    • プロセスとは”操作”要素と同義である

  • プロセスは、”〇”で記述し、”〇”の中に記述されたテキストを、そのプロセスの名前とする

  • データの流れは”→”で記述し、”ー” 側(始端)からデータが供給され、”→”側(終端)でデータが消費される

  • ”→”上を流れるデータは、ドメインで定義されたデータ型の一つ以上の変数として定義される

  • データの流れは、以下の3種類のうち、どれかであり、それぞれ、

    • プロセス(A)と別のプロセス(B)をつなぐ

      • プロセス(A)が、データの流れで定義された変数(群)のデータを生成し、別のプロセス(B)がそのデータを消費する

    • 終端のみ、プロセスにつながる

      • データフローモデルの外から、終端のプロセスに、データの流れで定義された変数(群)のデータが供給される

        • ※ ドメイン ファンクションの引数、または、状態遷移を引き起こした事象(イベント)の付加データの場合

    • 始端のみ、プロセスにつながる

      • 始端のプロセスが、データの流れで定義された変数(群)のデータを生成し、データフローモデルの外にデータを提供する

        • ※ 概念インスタンスの削除、概念インスタンスの特徴値の更新、概念インスタンス間のリンクの切張、事象(イベントの生成)、Bridge の起動等

  • 一つのデータの流れは分岐してよい、つまり、始端が一つで終端が複数のデータの流れを定義してよい

  • 一つのプロセスは、複数のデータの流れの終端・始端を持つ

  • 一つのプロセスは、終端として接続しているデータの流れから受信したデータを元に、あらかじめ定義された何らかの変換処理を行い、始端として接続されたデータの流れに変換によって生成された値を流す

  • データの流れ上のデータの型が真偽値の場合で、かつ、そのデータの流れの始点が条件判定のプロセスの場合は、データの値が True の時だけ、終点のプロセスが起動される

概念モデリングの概念振舞モデルにおけるアクションは、通常のプログラミングの様な、処理途中でのエラーや例外等の発生による途中終了は許されていません。概念モデルは、モデル化対象の現実世界の写しです。アクションの途中で異常終了するという事は、現実世界がそこで消滅するという事と同義であり、ビジネスモデル上のビジネスシナリオや制御モデル上の制御が重大な欠陥を抱えている事を意味します。作成した概念振舞モデルが中途半端に異常終了する場合は、異常状態発生の原因を究明し、必要であれば、概念情報モデルから見直して、異常終了しないモデルに作り変えなければなりません。
概念モデルでは、ドメインファンクションの場合は起動から、状態モデルの場合は事象受信による遷移先の状態のエントリアクション起動から、データフローモデルの実行セマンティクスに従って一通り最後まで記述されたアクションが実行されるような概念モデルになっていなければなりません。

実行ルール(実行セマンティクス)

  • データフローを流れるデータは離散的であり、始端から供給されて終端で消費される

  • 終端で接続された全てのデータの流れにデータが供給されたプロセスは、あらかじめ定義された何らかの変換処理の実行を開始し、始端で接続された全てのデータの流れにデータを供給する

  • 変換処理の実行には幾ばくかの時間がかかる

  • 始端が一つで終端が複数のデータの流れにデータが供給された時は、終端側に等しくデータが供給される

概念情報モデルの操作」の章でも説明しましたが、“事象”は、同時並行的に発生すると考えます。従って、“アクション”の実行もまた同時並行的に行われ、インスタンスの生成や削除、リンクの切り貼り、特徴値の更新が同時並行的に行われます。

※ 概念モデルは現実世界の写しです。現実の世界でも物事は様々な主体が独立並行して変化しているので、概念モデル上でもそのように扱います。

補足

複数の“アクション”の同時実行で、同じ対象への状態更新・参照の競合が発生してしまう場合は、概念情報モデルのクラスや関係の定義を見直して、競合が解決できるよう修正が必要です。

“アクション”を定義する際の注意点がもう一つあります。それは、サービスドメインやインフラストラクチャドメイン(「ドメインと IT システム構築」を参照のこと)が担う処理を排除することです。特にWebやPC、スマートフォンのアプリ開発の経験があるプログラマーは知らず知らずのうち、ヒューマンインタフェースのモジュールが担うべき処理を混入させてしまったり、データベース利用に慣れた技術者は情報の格納に関するリレーショナルデータベース特有の処理を混入してしまったりするので注意が必要です。

”事象“の発生は、何らかの手段を使ったITシステムへの情報入力が対応します。利用可能な手段としては、人が操作するGUIやCUI、スクリプトによる一括実行、REST APIによる他のサービスからの起動等、様々な手段が存在します。アプリケーションドメインを実装する際に対応付けるサービスドメインは交換可能になっていることが望ましいので、”アクション“を定義する際、複数の手段を頭に描き、手段を交換しても影響を受けない、モデル化対象のドメインの文脈にのみ依存する処理の抽出を心がけましょう。

アクション記述の注意点をまとめておきます。

  • アクションは完了する事

  • アクションで扱う変数は概念情報モデルで定義されたもののみ使う事

  • 基本単位の処理はデータフローに基づいて実行される事

  • 他のドメインの処理を混入させない

実行セマンティクス

記述した“アクション”を“実行”する際の決まり事を幾つか紹介しましたが、このような決まり事を“実行セマンティクス”と呼びます。“実行セマンティクス”を明確に定義することにより、作成した概念情報モデル(+初期状態)と概念振舞モデルを組み合わせて、シミュレーションや概念モデルの正しさが検証できます。

以上を踏まえ、“商品販売”ドメインの概念情報モデルを使って“アクション”の例を紹介します。

このドメインでは、ビジネスシナリオに、

“商品を注文する”

という事象があるはずです。この事象は、注文する主体、つまり、“顧客”を特定するための情報と注文の対象となる“商品”を特定するための情報が伴います。ほかに、注文する“個数”等、注文に関わる情報も付随します。

※ この様に、ビジネスシナリオに沿って概念モデルの要素を見つけていくことを、“モデル化対象ドメインの文脈で”としています。

その事象の発生を受けて、事象が発生した時の“概念情報モデルの状態”を、ある顧客が特定の商品を注文した“状態”に変化させます。その“状態”をインスタンスとリンクで図示すると以下の様になるはずです。

画像2
図2. 概念インスタンス、リンクで状態変化を表す

状態を変化させるための処理を、概念情報モデルで定義されたクラスと関係を使って書き下すと、以下の様な流れになります。

  1. “商品を注文する”.“顧客ID”を使って、該当する“顧客”クラスのインスタンスを検索する

  2. “商品を注文する”.“商品コード”を使って、該当する“商品”クラスのインスタンスを検索する

  3. “注文”クラスのインスタンスを一つ作成し、“商品”.”単価“×”商品を注文する“.”個数“から”金額を計算し、作成した“注文”インスタンスの特徴値を全て確定します。

  4. “顧客”、“商品”のインスタンスの間に、“注文”インスタンスを使って、関係“R1”のリンクを張る。

この一連の流れで出来上がる“状態”は、前に図示したインスタンスの最終状態に合致します。
これで振舞に関するモデリングが完了したようにも思えますが、そうではありません。
例えば、“商品を注文する”.“顧客ID”に該当する“顧客”クラスのインスタンスが存在していない場合の対応や、“商品を注文する”.“商品コード”に該当する“商品”クラスのインスタンスが存在しない、あるいは、存在はするものの“商品”.“在庫”が0の場合の対応が、上の“アクション”には含まれていません。このままでは、実用に足るITシステムを構築するのは無理です。アクションには、この様な様々なケースへの対処も含まれていなければなりません。
例えば、

  • 1.の問合せ操作による検索が終わった時点で、検索結果の集合が空だった場合の処理を追加する

  • “注文”インスタンスは作成できないので、“顧客IDに該当するインスタンス無し”という“事象”を“顧客ID”を付与して生成し、処理を終える

  • 2.の問合せ操作も検索結果の集合が空だった場合の処理を追加する

  • “注文”インスタンスは作成できないので、“商品コードに該当するインスタンス無し”という“事象”を“商品コード”を付与して生成し、処理を終える

  • 3.の計算において“商品”.”在庫“>=”商品を注文する“.”個数”のチェックを入れる

  • “注文”インスタンスは作成できない?ので、“在庫なし”という“事象”を“顧客ID”、“商品コード”、“個数”を加えて生成して、処理を終える

といった状態への対応は、最低限必要です。
参考までに、この処理を追加したデータフローを図に示しておきます。

画像3
図3. データフローサンプル

データフローの実行セマンティクスに従って処理の流れを確認し、顧客ID、商品コード共に対応するインスタンスがどちらも存在しない場合は、それぞれに対応する事象も両方発生することを確認してください。

さて、概念振舞モデルの構築においては、それぞれの状態について、その状態がモデル化対象のビジネスの文脈でどういう意味を持つのかを深く考察するという作業が必要です。
例えば、顧客IDに該当するインスタンスが無いというケースを考えてみます。そもそも、概念情報モデルに“顧客”というクラスが定義されているということは、ビジネスシナリオ上、

“商品を注文できる顧客は、あらかじめ登録されている”

事を意味するはずです。そうすると、このケースでは、
該当する顧客インスタンスが存在しない場合は、

  • 注文を行うためには事前の顧客登録が必要

  • 初めての注文時に同時に顧客登録も行う

という少なくとも二つのビジネスシナリオがありえます。最初のシナリオを選択した場合は、上に挙げたアクションの修正で十分ですが、二番目を選択する場合を考えると、

  • “商品を注文する”という“事象”の引数に顧客登録に必要な情報を加える

  • 仮登録しておいて後で必要な情報を後で“状態”にセットする

など、複数のケースが想定可能です。更に言えば、コンビニやスーパーでの買い物の様に、不特定の客が購入するようなビジネスシナリオであれば、そもそも、“顧客”というクラスは不要なのではないか、あるいは、“注文”という名前は不適切で、単なる“購入”なのではないか、等々なケースが考えられます。この様な場合は、適切と思われるケースを選択して、概念情報モデルを見直してから、また、概念振舞モデルの作業に戻ります。

次に、“商品を注文する”.“商品コード”に対応する“商品”インスタンスが無いという状態を考えてみましょう。あり得るケースとしては、

  • オペレーターの入力ミス

  • 商品インスタンスの作成忘れ

  • ITシステムでのメッセージ伝達時のデータ化け

などが考えられます。この様なケースは、概念情報モデルの状態の一貫性を保持するための条件に応じた処理を定義するだけで十分でしょう。
では、“商品”.“在庫”が“商品を注文する”.“個数”より少ない場合はどうでしょう。このケースについても、“顧客”インスタンスのケースと同様、様々なケースが想定可能です。

“概念情報モデル”の作成の時と同様、“概念振舞モデル”の作成についても、詳細化していく過程でビジネスシーンの取り扱いに関する様々な候補が出てきます。そのような検討課題の抽出と、どのような選択をするかを検討して決めていく過程をモデリングと呼びます。細かいケースを明確に決めていく過程は、ビジネスモデルの詳細を確定していく工程であり、概念モデリングはそれを支援する手段であるといえるでしょう。

事象の引数

例で示した通り、“事象”は一つ以上の引数を伴う場合があります。それぞれの引数は名前とデータ型、それが何であるかの説明文で定義します。名前、データ型とも、モデル化対象のドメインの文脈において意味のあるものを選択します。データ型は、「概念情報モデル」のデータ型で紹介した、数値、文字列、列挙、複合型のどれかです。特徴値のデータ型として定義されたデータ型を使っても構いません。

事前条件と事後条件

“商品を注文する”という“事象”に対する“アクション”について紹介しました。
顧客インスタンスが無い状態等も含めたアクションから、“事象”発生時点の“状態”と“アクション”実行完了時点の”状態“の組を抜き出すと、

※ 可読性を考慮して簡略化して、記載しています

となり、それぞれがモデル化対象ドメインのビジネス上何らかの意味を持っています。
発生時点の“状態”が満たす条件を、概念情報モデルの定義内容で記述したものを、“事前条件”、完了時点の“状態”が満たす条件を、概念情報モデルの定義内容と、概念振舞モデルの“事象”で記述したものを、“事後条件”と呼ぶことにします。
“事後条件”は、ビジネスシナリオのゴールが達成された“状態”が満たすべき条件であるという見方ができ、“事象”に対する“事前条件”と“事後条件”の組を明らかにしておけば、あるビジネスシナリオのゴール達成の前提になる“状態”が満たすべき条件の逆引きが可能になります。
“事象”に関する“事前条件”、”事後条件“の組がビジネス的に特に意味がある場合、振舞モデルの情報として記載しておきます。

前述の通り、“アクション”の記述は一般的に使われている高級言語を使っても構わないのですが、紹介した操作の基本単位と実行セマンティクスを満たす概念振舞モデルのアクションを記述するための専用言語の例として、xtUML の OAL(Object Action Language) を参考までに紹介しておきます。

この言語は、BridgePointというxtUML用のツールを使って、アクション記述と記述したアクションの実行が可能です。また、記述からの各種プログラミング言語で書かれたコードを生成可能です。

実務上、必要がない限りは、この様なアクションを記述する専用言語は使わなくてもよいですが、一般的な高級言語を使ったコードで定義するのであれば、データフロー処理が記述できる LINQ や並行性が記述できる asynchronous といったアクション記述の実行セマンティクスに近いプログラミングモデルを持っているC#がおすすめです。
C#のプログラムの実行環境である、.Visual Studio は、T4 Tempate というコード生成で便利な機能が使えるので、後述の、概念振舞モデルの「実装への変換」で説明する方法を使って、C#で記述したアクションの別のプログラミング言語で記述されたコードへ自動変換が可能です。

※ Project Roslynは、コード自動生成オタクにとっては涎垂の技術です。まぁ、C#で書いたプログラムを態々、JavaやPython に変換する好きモノはほとんどいないと思いますが、HWのリソースが十分でない小型組込み機器で動作させるためにCやC++に変換するというのは実用上ありなんじゃないかと、筆者は経験上考えています。

概念振舞モデルを実装する

作成した概念振舞モデルからの実装の構築は、「ドメインとITシステム構築」の章で解説した方法で行います。
構築対象のITシステムに求められる非機能要件に従って、サービスドメイン、インフラストラクチャドメインを選択し、概念振舞モデルの概念情報モデルと他のドメインの要素を対応付け、実装に変換するためのルールを定義して、概念振舞モデルの概念情報モデルの状態リポジトリからインスタンスを順次取り出して、ルールを適用して、プログラミングコードや、設定を生み出していきます。

前述の“商品を注文する”という“事象”を例に、具体的な実装への変換の様を説明していきます。

考慮する非機能要件は、ITシステムの利用ユーザー増加に対応するためのスケーラビリティと、許可されたユーザーのみが利用できることの二点とします。

  • スケーラビリティ

  • アクセス制御

説明を簡略化するため、ここでは、アプリケーションドメインを直接インフラストラクチャドメインに対応するというシンプルな形で説明を行います。
実装に必要なインフラストラクチャドメインは、

  • 概念情報モデルのリポジトリ

  • 概念振舞モデルの実行環境

  • 他ドメインへの事象の伝達

  • 概念振舞モデルを実装するプログラミング言語

です。

画像4
図4. 概念モデルの実装

具体的な実装技術・サービスは、それぞれ以下の様に選択することにします。

https://gist.github.com/kae-made/2d8ea32bbbe11bb51ad8aaa17f3700cb#file-mapping-infra-service-md

選択した3つのサービスは、スケーラビリティがあり、アクセス制御も備えています。

画像5
図5. In Memory からスケーラブルなクラウド実装へ

Azure Digital Twins との対応付けは、「概念情報モデルを使う」で説明した方法で実装に変換できます。概念情報モデルへの操作は、Azure Digital TwinsのAPIに対応付けられるので、あらかじめ、各操作をAPIで実現するパターンを決めておき、アクションに登場する操作の基本単位を定義済みのパターンで置き換えてプログラムコードを構成していきます。Azure Digital Twinsインスタンスへの参照も必要なので、コードに織り込みます。
実行環境へのマッピングは、図に示すように、

  • “事象”をアクションに伝達する仕組み

  • Function への割り付け単位

  • “事象”を生成したユーザー権限

に対するルールの定義が必要です。基本は、デザインパターンのFaçadeパターンに従って割り付け、“事象”の伝達は、Azure Functions の HTTP Binding を割り付けます。Function の起動の際、ユーザーのコンテキストも扱うことができるので、ユーザー権限管理はその機構に対応付けます。

アクション記述の実行中に発生させた“事象”は、Azure Event Hubに送信する事に対応付けます。これは「概念情報モデルをITシステムに組み込む」の章の「アーキテクチャ」の節で紹介した“メッセージ駆動型のアーキテクチャ”の考えに従った、選択でもあり、Azure Event Hubに“事象”をメッセージとして送信してしまえば、Publisher & Subscriberモデルにより、その事象発生を受信したい任意の他のサービスを後付けできます。

プログラミング言語への対応付けは、

  • アクションを構成する操作の基本単位への実装パターン

  • アクションの実行セマンティクスと利用するプログラミング言語のセマンティクスの対応付けと、それに対する実装パターン

が必要です。サービスドメインを使う場合は、サービスドメインで定義されたインフラストラクチャドメインへの対応ルールに従ったコードへの変換も追加されます。

概念振舞モデルの実装への変換の基本的なやり方の説明は以上です。説明において、変換の方法が、アクションで記述した中身に一切依存せず解説されている事に注目してください。これはつまり、概念振舞モデルの実装方法の“やり方に関する定義作業”は、概念情報モデルの時と同様、特定のアプリケーションドメインや特定の処理に関係なく、独立して並行に行えることを意味し、また、一旦実装方法を定義してしまえば、様々なアプリケーションドメインで再利用可能であることを意味します。

※ 動かしたいシナリオを一旦モデル化し、概念振舞モデルの概念情報モデルの状態からインスタンスを取り出して、あらかじめ定義していたパターンを適用してプログラミングコードを自動生成する、初めて聞いた読者の中には、「本当にそんなことができるの?」と疑問に思う読者がいるかもしれません。実はこのやり方は、WebページのデザインではHTMLとCSSで当たり前に使われているテクニックと基本は一緒です。
世の中には非常に多くのプログラミング言語が存在していますが、プログラミング言語は、シンタックス(見栄え)とセマンティクス(意味)から成り立っているので、新しいプログラミング言語に挑戦する場合には、この二つを分けて理解すると、より早くその言語を習得できます。

状態モデル

振舞において、“事象”が発生した時に、“事前条件”と“事後条件”が組として存在することを述べました。それぞれの“状態”を角が丸の四角で表現すると、以下の図のように描けます。

画像6
図6. 状態モデルの基本

ある“状態”で“事象”が発生した時に、別の“状態”に移行することを“状態遷移”と呼びます。図の“状態“間をつなぐ矢印が”状態遷移”を意味します。

前に述べた振舞は、概念情報モデル全体の状態を変えるモデルでした。概念情報モデルの概念クラスの中には、物理法則やビジネスルールに従って、そのインスタンスが、ある“事象”が発生した時々の“状態”に応じて“状態遷移”を引き起こしながら、それに伴う“アクション”を実行して、ドメインにおける一定の役割を担う概念が存在します。そのような、概念クラスに紐づいた、一連の“状態遷移”をまとめたものを、“状態モデル”と呼び、それを図示化したものを“状態遷移図”と呼ぶことにします。それぞれの“状態”には、モデル化対象ドメインの文脈において意味のある名前を付けます。

画像7
図7. 状態モデル=概念インスタンスに割り当てられた状態マシンの雛形

本稿で解説する“状態モデル”は、 “状態”毎に“アクション”を紐づけて定義します。“状態モデル”が定義されているクラスのインスタンスは、“状態モデル”で定義された“状態”のうち、どれか一つの“状態”にいるものとされます。その“状態”にある時に、“状態遷移”を引き起こす“事象”が発生した時に、遷移先の“状態”に紐づいた“アクション”が実行され、実行が完了した時点で、新しい“状態”が確定するものとします。
また、“状態機械”は、“状態”が確定後、“事象”を受信出来ます。

画像8
図8. 状態モデルを雛形にした、概念インスタンスの状態機械は同時並行的に動く

この、“状態”、“状態遷移”、“アクション”の実行、“状態”の確定は、クラスではなく、それぞれのインスタンスに紐づけられていることに注意してください。

“状態モデル”に従って動く仕組みを“状態機械”と言います。“状態モデル”が定義されたクラスのインスタンスは、それぞれの“状態機械”を持って振舞います。“状態モデル”に従ったインスタンスの遷移の様は、インスタンスの“ライフサイクル”と呼びます。

モデル化対象ドメインの概念情報モデルで必要なクラスの“状態モデル”をすべて定義してやれば、概念情報モデルのインスタンスの状態、ドメインに紐づいたアクション群、クラスの“情報モデル”を使って、モデル化対象ドメインのビジネスシナリオを実際に動かして試すことができ、構築した概念モデルが想定通りのビジネスシナリオを再現可能かという概念モデルの確からしさのチェックや、特定のインスタンス状態にあるときの想定されるビジネスシナリオのシミュレーションが可能になります。

状態モデルのパターン

状態モデルは大きく二つのパターンに分類できます。

  • 生成消滅型

  • 巡回型

生成消滅型

“商品販売”の“注文”クラスを例に考えてみます。このクラスのインスタンスは、“商品を発注する”という事象が発生した時に生成されて、対応する商品が引き当てられ、顧客への課金処理が成されて、商品が配送された時点で、削除される、という流れの元に存在すると考えた場合、図のようにそのライフサイクルを状態遷移図で表現できます。

画像9
図9. 生成消滅型の状態モデル

 この様に、インスタンスが生成して一連の状態遷移とアクションの実行を行って消滅するようなライフサイクルのパターンを持つものを“生成消滅型”と分類できます。

巡回型

“装置管理”の“装置”クラスを例に考えてみます。このクラスのインスタンスは、現実世界の実際の装置が対応しているので、ラインに設置された後は、スタンバイ状態、仕掛り製品が割り当てられて、製造仕様に基づいて加工作業を行い、加工作業が終わったら次の加工に備えて準備を行い、スタンバイ状態に戻る、というライフサイクルを繰り返します。

画像10
図10. 巡回型の状態モデル

この様に、インスタンスが同じライフサイクルを繰り返すようなパターンを持つものを“巡回型”と呼びます。

概念情報モデルのクラスに対して定義される“状態モデル”は、途中の状態遷移の枝分かれはあるにしても、経験上、この二つのパターンのどちらかの派生としてモデル化できます。また、複雑な状態遷移を持つ状態モデルを使った概念モデルのチェックやシミュレーションは非常に煩雑かつ間違いやすいので、状態モデルを構築する場合は、なるべく、この二つのパターンを出発点とすることを推奨します。

状態遷移表

例示した“装置”の“状態遷移図”には状態Aの時に事象Bが発生した時に、何が起こるか、何をしなければならないかは一切書かれていません。より厳密にインスタンスの振舞を定義したい場合は、“事象”を行方向、“状態”を列方向にした表を作成します。
“状態遷移図”で定義された“状態遷移”を元に、対応する項目を埋めていくと、空欄が残ります。この空欄それぞれに対し、モデル化対象ドメインの文脈において

  • 無視できる - I(Ignoreの先頭文字)

  • 起こりえない - C(Can‘t Happenの先頭文字)

のどちらであるかを熟慮し、埋めていきます。

この手順で出来上がった表を“状態遷移表”と呼びます。“無視できる”は、ビジネスシナリオ上、インスタンスがその状態にある場合に、事象が発生したら、その事象はスルーしてかまわないということです。“起こりえない”は、例えば、“装置”の状態が、“スタンバイ”である場合に“加工完了”の事象は、物理的に起きえないというような状況を意味します。

画像11
図11. 状態遷移を厳格に定義する”状態遷移表”

概念モデルのチェックの途中で、この“起こりえない”が発生したら、概念モデルのどこかが間違っている可能性があるので、原因を調べて概念モデルを修正する必要があります。この様なテストを行った後に、実装に変換して、実際にITシステム上で稼働しているときに“起こりえない”が発生した場合は、システムに何らかの異常事態が発生していると考えるのが妥当です。

本稿で解説している”概念モデリング”の”状態モデル”は、イベントを受信した時に”状態遷移表”の宣言に従って、次の遷移先の状態が決まり、遷移先の状態に定義されたエントリアクションの実行が完了した時点で遷移が確定するという実行セマンティクスを採用しています。このことにより、単に遷移先だけでなく、ある状態にある概念インスタンスの遷移に関するアクションも含めた振舞いが一位に定まるという特性を持っています。

スーパークラス、サブクラスの状態モデル

本稿で解説している概念情報モデルの、スーパークラス、サブクラスの関係は、形式的には、スーパークラスのインスタンスが一個存在する場合は、サブクラスのどれかのクラスで対応するインスタンスが一個だけ存在するというだけの意味です。“状態モデル”はクラスに対して定義できるので、スーパークラス、サブクラスの関係にあるクラス群に対しては、スーパークラス、及び、それぞれのサブクラスに対して異なる“状態モデル”を定義可能です。

画像12
図12. 概念クラスは Relationship の定義に関係なく、一つの状態モデルを定義できる

オブジェクト指向プログラミングにおける“継承”とは無関係なので注意していください。

サブクラスマイグレーション

スーパークラス、サブクラスの関係を持つクラスは、以下の二種類に分類できます。

  • 種別固定型

  • マイグレーション型

種別固定型

モデル化対象ドメインの文脈において、サブクラスのインスタンスが生成されたら削除されるまでずっとそのサブクラスが変わらない関係があります。例えば、原子力発電所が地熱発電所に途中で変化することは、まずあり得ないでしょう。

画像20
図13. 種別固定の分類型

マイグレーション型

モデル化対象ドメインの文脈において、あるサブクラスのインスタンスが生成された後、発生した事象や概念情報モデルの状態変化に伴い、スーパークラスのインスタンスはそのままで、サブクラスのインスタンスが別のサブクラスのインスタンスに変化するものです。

画像21
図14. ライフサイクルに従ったマイグレーション型

装置は、その時の状態に応じて、“スタンバイ状態の装置”だったり、“製造準備中の装置”にサブクラスのインスタンスが移り変わります。この時、アクションでは、

  1. R_E10のリンクを切って、“スタンバイ状態の装置”のインスタンスを削除

  2. “製造準備中の装置”のインスタンスを生成し、R_E10で“装置”のインスタンスとリンクを張る

という処理を実行することになります。

※ スーバークラス、サブクラスの関係を定義する時に、どちらの分類を選択するべきかに関する明確な指針はありません。モデル作成者の判断に任されています。
※ マイグレーション型の場合、スーパークラスの状態遷移図で全体の振舞を定義し、サブクラス側でそれぞれの時点での詳細の振舞を状態遷移図で定義すると、すっきりした状態遷移図が出来上がります。実行セマンティクスが明確に定義された、UMLの階層型状態遷移図といった趣です。

多態事象

英語では、”Polymorphic Event”と言います。Super Sub Relationship の関係が定義された概念クラス群において、Super 側の概念クラスの状態モデルで定義された事象を、Sub 側の概念クラスの状態モデルが受信するものです。

図15. Polymorphic Event

オブジェクト指向プログラミングに馴染んだ読者の中には、”多態事象”=”オブジェクト指向プログラミングの Polymorphism”と考えてしまう人もいるかもしれませんが、別物です。
多態事象は、単なる便宜的な記法にすぎません。
多態事象が無い場合、図の事象'E3' を状態マシンに送信する場合、A の概念インスタンスから Super-Sub Relationship のリンクを辿って B か C の概念インスタンスを取り出し、その時点でリンクされたどちらかの状態マシンを明示的に区別して事象'E3'を送信しなければなりませんが、多態事象を使えば、Super-Sub Relationship のリンクを辿ることなく、A の概念インスタンスの状態マシンに、A で定義された事象’E3’ を送信すれば事足ります。

Super 側の概念クラスの状態モデルで定義された多態事象の全てを Sub 側の概念クラスの状態モデルで遷移として使用する必要はありません。

図16. Polymorphic Event の部分利用

Sub 側の概念クラス群のそれぞれに対して状態モデルが定義されるかどうかは、ひとえにモデル化対象の主題領域に拠ります。モデル作成者が、その概念インスタンスの振舞を状態モデルとして記述する必要が無いと判断すれば、無理やり状態モデルを定義する必要は全くありません。上の図では、R1、R2 で定義された Supuer-Sub Relationship に参加する B、C、D、E の4つの概念クラスの内、状態モデルが定義されているのは、B と E だけで、残りの C、D は状態モデルが定義されていません。この様な場合、A の概念インスタンスの状態マシンに対して事象’E3’を送信した場合、R1 でリンクされたサブ側の概念インスタンスが、

  • B の概念インスタンスがリンクされている場合

    • B の概念インスタンスの状態マシンが E3 を受け取る

  • C の概念インスタンスがリンクされている場合

    • E3 は無視される

事象’E4’が送信された場合は、

  • B の概念インスタンスがリンクされている場合

    • E4 は無視される

  • C の概念インスタンスがリンクされている場合で、かつ、R2 で

    • D の概念インスタンスにリンクされている場合

      • E4 は無視される

    • E の概念インスタンスにリンクされている場合

      • E の概念インスタンスの状態マシンが E3 を受け取る

になります。文中の”無視”とは、「状態遷移表」のセクションで解説した”無視できる”と同等です。

interface で定義された全ての method を、その interface を実装する class で実装しなければならない C# や Java の inteface と”多態事象”は異なるので混同しないでください。

状態モデルの実行セマンティクス

“状態モデル”で定義された状態遷移を引き起こす“事象”は、クラスに対して紐づけられ、ここの“事象”の発生を受け取るのは、クラスのインスタンスの“状態機械”です。
“状態機械”は、“事象”を受け取ると、“状態遷移”が定義されている場合は、遷移先の“状態”に定義された“アクション”を実行し、実行完了後に新しい“状態”を確定します。“アクション”の実行には、0ではない有限の時間がかかるものとします。
“無視できる”場合は、状態遷移は発生せず、何も起こりません。“起こりえない”が発生したら、“状態機械”は、サービスドメインに、“起こりえない”という事象を通知し、動きを止めます。
複数の“状態機械”が存在する場合、それぞれの“状態機械”は同時並行的に無関係に“状態遷移”と“アクション”の実行が行われるものとします。
それぞれの“状態機械”に向けた“事象”が発生している場合、その“事象”を受け取る順番は不確定です。

※ 不確定とは、どちらの順番の受け取りでもよいし、同時もありうるということです

画像13
図17. 異なる状態マシンの事象受け取りは無関係

一つの“状態機械”が受け取る“事象”が複数発生している場合は、その“事象”が同じ状態機械で生成された場合は、生成された順番で受け取り、別の場所で生成された場合は、どちらが先に受け取られるかは不確定です。

画像14
図18. 事象受信の順序

自身に向けた事象

アクションの定義において、その状態機械のインスタンスに向けて、事象を発生させることができます。その場合、他のインスタンスの状態機械や、ドメインアクションが発生させた事象よりも先に受け取れるものとします。 

遅延事象

アクションの定義において、“事象”の発生時間を遅らせることが可能です。遅延事象は、例えば、1分ごとに定期的に注目しているエンティティの値をチェックする、といったような実世界のシナリオをモデル化する際に便利です。

画像15
図19. 遅延事象

冒頭に解説した概念振舞モデルのアクションでも言及した通り、モデル化対象ドメインの文脈におけるビジネスシナリオで一連の順序があるような流れを、複数の“状態機械”で担う場合は、ビジネスシナリオ上の想定順序を満たすような概念情報モデルと状態モデルを構築しなければなりません。

状態遷移を引き起こす事象の引数シグネチャ

ある状態(Sd)への遷移が定義された状態が複数ある(例えば、Sa, Sb)場合、それぞれの状態から遷移を引き起こす事象は異なっていても構いません。例えば、Sa->Sd は E1、Sb->Sdは E2などでよいということです。
しかし、Sd への遷移が発生した際に実行されるのは Sd に定義されたエントリアクションなので、それら遷移を引き起こす事象(例では、E1、E2)が引数を伴う場合は、全ての事象は、同じデータ型、同じ名前(意味的にも同一)の引数群を伴うように定義されていなければなりません。

以上の説明を踏まえ、一部ですが、“状態モデル”の概念情報モデルを参考までに図示しておきます。

画像16
図20. 状態モデルのメタモデル概要

外部から・へのデータフローモデルのデータの流れ

データフローモデルは、状態アクションとドメイン ファンクションの処理の記述を行います。
それを踏まえ、データフローの始端・終端がデータフローモデルの外の場合の正体を挙げておきます。

始端が外部のデータフローのデータソース

  • ドメイン ファンクションの場合

    • ドメイン ファンクションの引数

  • 状態アクションの場合

    • 状態モデルへのイベント引数

  • ドメイン ファンクション、状態アクション共に

    • 概念クラスのインスタンス、及び、特徴値とリンク

終点が外部のデータフローのデータシンク

  • ドメイン ファンクションの場合

    • ドメイン ファンクションへの戻り値

  • ドメイン ファンクション、状態アクション共に

    • 状態モデルのイベントインスタンス

    • 概念クラスのインスタンス、及び、特徴値とリンク

概念モデリングの際、状態モデルへのイベントインスタンスは、ドメイン ファンクションの処理の一環としての生成と定義しても良いし、現実の世界の事象発生と同じく、モデル上は、どこからともなく生成されると考えても問題ありません。

UML で定義された状態モデルとの比較

本稿で解説している状態モデルの記法は、UML で定義された描画方法に従っています。UML の状態モデルでは、状態の階層化、遷移上や、状態確定後、状態遷移前等でのアクション実行等、多彩な記述要素が定義されています。本稿で解説しているのは、単階層でかつ、状態遷移発生時のエントリアクションのみを使った状態モデルなので、「そんなシンプルな道具立てで足りるの?」と不安になったり、「せっかく階層化や色んなアクション実行があるんだから使いたい」と不満に思う読者がいるかもしれません。しかしこのような懸念は無用です。UMLで定義された要素はそれぞれの歴史的背景から生まれたものではあるのですが、本稿で解説している様な、概念情報モデルで定義された概念クラスのインスタンスの振舞を状態モデルで定義する場合には、これで十分だということが経験から分かっています。現実世界を思い浮かべてみてください。状態マシンを持つであろうインスタンス群が同時並行的に動くことになります。この様な描像を正確に誤解なく表現するのには、シンプルな状態モデルが適しています。

概念モデリングにおける状態とは

概念情報モデルを使う”において、モデル化対象の現実世界である 圏W と、特徴値の値が確定している概念インスタンス群と、二つの概念インスタンス間のリンク群で記述される 圏I のモデルは自然同値であり、1対1対応にあると説明しました。そして、概念情報モデルは、圏I の在り様を規定する、結果として、圏W の在り様も規定するスキーマ圏(圏C)であると、解説しました。スキーマ圏である概念情報モデルの記述に従って構成された 圏I のモデルは、モデル化対象の現実世界のある時点でのスナップショットに相当します。モデル化対象の現実世界は、事象の発生に伴って変化していきます。
概念モデリングにおいては、事象もまた、モデル化対象の現実世界からモデルとして抽出するべき何かの一種として考えます。

図21. 事象

変化は、圏I のモデルにおける、概念インスタンスの増減、特徴値の値変化、リンクの増減で記述されます。
図に挙げた、目に見える様な出来事に加えて、なんらかの自然法則に従った時間経過に伴う状態変化の場合は、自然法則から導かれる一定間隔で”時間経過”という事象が発生しているものと考えます。

ある時点のスナップショットと事象発生後の次のスナップショットを考えてみます。それぞれのスナップショットは、各時点ごとの人間の認識の単位(だからこそ特徴値の値は全て確定している)であり、現実世界全体の状態を表現しています。ある時点のスナップショットと事象発生後の次のスナップショットで状態が変わるということは、状態遷移を起こしていると考えられるとともに、概念インスタンスの生成削除、特徴値の参照更新、リンクの生成削除などのアクション実行が、状態遷移の間に発生していることも意味します。モデル化対象の現実世界のダイナミクスを記述するという事は、この時間軸にならんだスナップショットを記述することを意味するわけです。

図22. 現実世界のダイナミクスのモデル化と、事象の局所化

この状態変化は、モデル化対象の現実世界全体を対象としています。単純なドメインなら問題ないのですが、モデリングを使って、理解し記述しなければならないようなドメインは複雑であり、このようなドメインの状態変化にそのまま無策で体当たりするのは良策とはいえないでしょう。
状態変化を引き起こす、それぞれの事象について考えてみましょう。事象の例として図に挙げた、それぞれの事象は何らかのもの(=概念インスタンス)に紐づいて局所的に発生しています。先に述べた時間経過による自然変化も、対象世界全体を対象にしているというよりも、局所的に発生する自然変化をそもそも想定しているといってよいでしょう。
以上を踏まえ、概念モデリングにおいては、事象は、概念インスタンスに紐づいて発生すると考えます。その事象発生に伴って発生する状態遷移と状態変化を引き起こすアクション実行もまた、その事象を紐づけた概念インスタンスに紐づくとしてモデル化を行います。

図23. 現実世界のダイナミクスと自然同値な 圏I のモデル

概念インスタンスとリンクを意味的に分類して概念クラスと関係(Relationship)を抽出し概念情報モデルを作成したように、概念インスタンスに紐づいた、それぞれの事象、状態、遷移、実行されるアクション、を分類して、事象(それぞれの事象の雛形)、状態(それぞれの状態の雛形)、遷移(それぞれの遷移の雛形)、アクション記述(それぞれの実行されるアクションの雛形)を定義し、記述すれば、概念クラスの状態モデルができあがります。このとき、概念モデリングにおいては、実行セマンティクスのセクションで解説したように、実行されるアクションは、遷移先の状態に紐づいていて、データフローセマンティクスによる一連のアクション実行が完了した時点で、遷移が確定すると考えるので、概念情報モデルにおいて、概念クラスを分類抽出する際に、同じ特徴値の組であるかが目安になるのと同様、圏I の状態群から 圏C の状態を分類抽出する際には、同じ実行されるアクションが紐づいているかどうかを基準として使えます。

老婆心ながら、ここで一つ注意を書いておきます。状態に紐づいた実行されるアクションの操作は、その状態が紐づいた概念クラスの特徴値だけには限定されず、圏I に存在する全ての概念インスタンス、及び、その値が確定した特徴値、リンクを対象とすることができます。
ここで、ん?と思ったあなた。察するに、オブジェクト指向プログラミングのカプセル化が頭をよぎっているのだと思います。概念モデリングはオブジェクト指向プログラミングではありません。日常の仕事や生活を思い浮かべてください。あなたが何かを行っている場合、操作対象は、あなたの体の中だけに閉じていることはなく、外界の様々な人、モノも含まれるでしょう。概念モデルは、現実世界を記述する体系であり、概念クラスに紐づいて定義された状態モデルのアクション記述が、リンクや別の概念インスタンスを操作対象にしていても、何ら不思議はありません。

状態モデルの実装への変換

状態モデルの実装への変換は、状態機械を実現する実装技術の組合せと状態モデルで定義された状態、状態遷移、事象のサービスドメインやインフラストラクチャドメインへの対応付けルールを定義で行います。このケースでも、利用する実装技術は、非機能要件を元に選択するのですが、ここでは、二つのよく使われそうな実装ルールを簡単に紹介しておきます。

インメモリによる状態機械の実装

状態、及び、状態遷移を管理するフレームワークライブラリを作成し、概念モデルで定義されたクラスの状態モデルを実装するやり方です。
概念クラスをオブジェクト指向言語のクラスで定義し、状態を保持するインスタンス変数を持たせます。状態遷移をテーブルで保持しておいて、今の状態と受信した事象から次の状態を決定し、その状態に紐づいたアクションを実装するメソッドをコールするというものです。インスタンス毎に事象のキューと実行スレッドを持たせて、事象のキューから事象を逐次取り出して処理をしていく、あるいは、ドメインに一つだけ事象のキューを用意して、シングルスレッドで地記事実行していく、といった実装で、状態モデルの実行セマンティクスに従った実装基盤が実現できます。

サーバーレスの仕組みを使った実装

もう一つは、Azure Functions の Durable Function を使う方法です。
この方法では、

  • パターン #2:ファンアウト/ファンイン

  • パターン #3:非同期 HTTP API

  • パターン #6:アグリゲーター

を組み合わせれば状態管理や同時並行の実行セマンティクスが実現可能です。
また、このパターンに基づいた、状態モデルの概念情報モデルの各要素への変換ルールも定義します。

本稿で紹介している“振舞”と”状態モデル“は、様々な方法で実装が可能です。それができる理由は、概念振舞モデルが、データフロー的な処理の流れをベースとした実行の同時並行性、無関係な事象の受け取り順序の不確定性を前提として構築されているからです。モデル化対象ドメインの文脈での競合はモデル上で解決するというのも実装技術の適用に自由度を与えている重要な要素の一つです。
これにより、構築した概念モデルを、小規模なHWリソースの機器にはインメモリのパターンで実装し、大規模でスケーラビリティが必要な場合は、コンテナ技術も利用可能な、Azure Function の Durable Functionでの実装を選択するなど、同じビジネスロジックを求められる非機能要件に応じた実装技術選択が可能になります。

より深く、状態モデルの実装方法を学びたい方は、「状態モデル実装実践ガイド」を参照してください。

競合と割当てパターン

これまでの説明の中で、モデル化対象ドメインの文脈において競合状態が発生しうる場合は、それを解決できるように概念モデルを構築する事、と何度か書いてきました。
ここでは、解決策の一つを紹介しておきます。

“商品販売”の“商品を注文する”という事象が発生した時の振舞で、

“商品”.“在庫” < “商品を注文する”.“個数”

の場合について考えます。この場合、ビジネスシナリオとして、

いずれどこかの時点で、在庫切れの商品は補充され、“商品”.“在庫”が増えるので、その時点で、“注文”の“個数”を割り当てる

と決めたとします。このシナリオを元に概念情報モデルを修正すると、以下の様なクラス図になります。

画像17
図24. 注文と引当ての競合

これで、在庫不足のために商品が補充されるまで待っている注文が存在することを、概念情報モデルで表せるようになります。しかし、顧客インスタンスは複数いて、それぞれが独立して任意の時点で注文するため、“商品”から見ると、“在庫待ち”クラス側の多重度は“*”になっています。つまり、一つの注文に対する在庫不足だけを考えればよいという事ではなく、一つの商品に対して競合する複数の在庫待ちが存在する場合があり、それらの要求を調停する必要があるわけです。この様な、限られたリソースに対する複数の利用要求割当てが生ずるケースは、ドメインの概念モデリングでは珍しくありません。

一つの解決策として、競合する要求を調停し、適宜要求者に割当てを行う、“在庫割当て(Stock Assigner)”というクラスを追加し、その“状態モデル”で順次割当てを行うという、モデル作成時によく使われるパターンを紹介しておきます。

画像18
図25. 競合の解決

一つの注文で個数を満たす在庫がない場合や、2つ以上の注文が競合する場合でも、図の状態モデルでその競合が解決できることを確認してみてください。
このモデルでは、要求待ちをしている複数のインスタンスからどれを選ぶかについて、“在庫待ち”.“開始時間”を参照して、一番長く待っているものを選ぶことにしています。これは、モデル化対象ドメインの文脈によって変わりうるアクションです。例えば、過去、より多くの商品購入をしている顧客の注文を優先するなどのルールがあれば、その判断をするのに必要な概念クラスや関係の追加、アクションへの条件判断や処理も追加することになります。
逆に、要求待ちをしている複数のインスタンスの選定条件に特段のルールがないケースも、それはそれで概念モデリングの過程ではありえます。それぞれのケースについて、熟考して明確化していく、これも概念モデリングでは重要な作業です。

本稿をここまで読んできて、概念モデリングへの理解をある程度深めた読者の中には、こういう場合に、「いちいち、同じようなクラス、関係、状態モデルを追加するのは、なんとなく、嫌な感じがする」と思われる方がいるかもしれないですね。その感覚は、概念モデリングを進める上で非常に重要です。
参考までに、

ある限られたリソースを複数の要求者に割り当てる

概念群を一般化たサービスドメインが存在すると考えて、概念モデルを作成して、アプリケーションドメインに割り当てる、という方法を紹介しておきます。

“テレメトリ”ドメインで説明した時と同様、ほぼ同じでちょっと違う状態モデルを多数定義しなくてよくなり、アプリケーションドメインの概念モデルがすっきりします。
Assignerのモデルは、前出のモデルとほぼ同じですが、サービスドメイン化した時の概念モデルは、以下の様になります。

画像19
図26. ドメイン分割によるモデルの整理

External Entity

本稿の”アクション”のセクションで、

  • ドメインの外側の仕組みからのデータ取得

というアクションを紹介しました。概念モデリングが対象とする主題領域を記述するのにデータ項目として必要ではあるが、そのデータが供給される仕組みの詳細は特に知らなくても良いようなデータ項目を供給するもので、それらを、”External Entity”と呼びます。概念モデリングにおいて、何を、”External Entity”として定義するかは、モデル作成者の決定に任されます。
代表的な ”External Entity”は、例えば”時間”です。大抵のビジネスシナリオでは、”今日は何年何月何日か”や、30分後は”何年何月何日何時か?”などアクションの過程で必要なる事が多いはずです。概念モデリングにおいては、それぞれの値が必要なだけであり、それぞれの値がどのような仕組みで供給されるのかはビジネスシナリオ上特に知る必要はないし、それが原子時計だろうが、クォーツ時計だろうが、電波時計だろうが、誰かがカレンダーや壁時計を見て知るなど、そのデータ項目を用意する方法は、そのビジネスシナリオから想起される誤差要件をクリアすれば、何を使ってもいいわけです。この様な場合、関連するデータ項目や演算等を提供する主体を分類し、”External Entity” として定義します。
データ項目取得や演算それぞれに名前を付けてて定義します。
これら、データ項目取得や演算等の操作要素は、ドメイン内のモデル要素から、ドメインの外の世界への橋渡しの役割を演じるので、”Bridge”と呼ぶことにします。Bridge は複数の入力と複数の出力を伴う事が出来ます。出力は無くても構いません。

例に挙げた”時間”では、

図27. External Entity の記述例

この様な記述により定義を行います。
※ 図では、Bridge の入出力の記述を、プログラミングのメソッドのシグネチャの形式を借りて行っています。
※ Bridge をプログラミングのメソッドシグネチャで記述した際に、引数無しで定義されるものがありますが、これは、Bridge への入力が無いことを意味するものではなく、どの External Entity のどの Bridge かを指定(識別)するデータの流れが入力(Birdge に相当するプロセスへの終端を持つデータの流れ)があることを意味します。

長年ソフトウェア開発に携わってきたエンジニアの場合、”External Entity” を見ると、ソフトウェア開発で使うサードパーティ製のライブラリモジュールの API を思い浮かべるかもしれませんが、全くの別物です。概念モデルは、モデル化対象の主題領域(ドメイン)の観点からの記述が基本です。External Entity は、あくまでもドメインの内部からの視点において、どの様に動いているかは知らない(主題ではないので知る必要はない)けれど、ドメインのシナリオを達成するのに必要なデータ変換や物理世界への通知等を行うためのエントリポイントとして定義するのが基本であり、Bridge も、その観点で定義していきます。
例えば、今時流行りの AI を使ったビジネスシナリオがモデル化対象だとします。ネットワーク越しに接続されたカメラから動画が送られてきて、その画像に写っている人を AI で抽出し、ある特定の場所に出入りした人をカウントし、人がいる時の会話をテキスト化するようなアクションを記述したい場合、”AI” という名前の External Entity を定義し、Bridge として以下を定義します。

  • ”人抽出” 

    • ”動画の識別子”を入力し、”人数:自然数”を出力

  • ”会話抽出”

    • ”動画の識別子”を入力し、”会話:文字列”を出力

この例では、”動画”に関わる事項もまた External Entity 定義の候補になるでしょう。AI に供給する動画を1分づつ取得するような場合、”Video” という External Entity を定義し、動画の”供給場所(例えば、どこかに設置されたカメラとか)の識別子”と”切り出す時間長”を入力とし、”動画の識別子”を出力とする Bridge を定義する様なケースです。

参考)アクション記述言語

この章では、概念振舞モデルの基本要素と記述方法を、データフロー図や状態遷移図等で解説してきました。概念情報モデルと状態モデルは、モデラーの脳内理解が混乱していると、その混乱がモデル図に反映され、モデルの成熟度の判定に使えるので、図で描くことは絶対推奨です。
一方、ドメイン ファンクションや 状態のエントリアクションの振舞のモデルをデータフロー図で描くことは、概要レベルの概念振舞モデルのレベルであれば推奨ではあるのですが、ソフトウェア最終成果物を自動生成する開発プロセスでは、厳密なレベルでのアクションの記述が必要になります。このレベルのアクションをデータフロー図で描いた場合、一つ一つが、膨大な〇と矢印で埋められた巨大な図になってしまいがちです。この様な図は、作成するのも、理解するのも、修正するのも非常に時間がかかってしまうので、実用的とは言えません。

概念モデリングの本質ではないのですが、実用上の要請から、データフローアクションを図形式ではなく、テキスト形式で記述する為の ”アクション記述用言語”を定義し、それを使ってアクション記述を行う方法が用意されています。例えば、概念モデリングの専用ツールの BridgePoint では、データフロー的な実行セマンティクスに基づいて定義された ”Object Action Language” というアクション記述用言語が提供されていて、実際のソフトウェア開発で使われています。
テキスト形式では、データフロー図上の〇が、一般的なプログラミング言語のメソッドコールと同じ形式の記述方法になりますが、あくまでも、

  • メソッドの引数と同等の形式 → データの流れの終端

  • メソッドの戻り値と同等の形式 → データの流れの始端

であり、

  • 変数と同等の形式 → データの流れ

    • 変数への代入と同等の形式 → データの流れの始端

    • 変数への参照と同等の形式 → データの流れの終端

であり、上から下に順番に記載されたテキストは、上から順番に実行されていくのではなく、データフロー図と同じ実行セマンティクスで実行される(必要なデータが揃った操作から実行され、複数の行が同時並行的に実行されることもありうる)ことになります。

ユースケースで概念振舞モデルを活用する

これまで説明してきた通り、概念モデリングにおいては、モデル化対象の現実世界のダイナミクスは、概念クラスで定義された状態モデルを雛形にして構成される、概念インスタンスの状態機械が、複数同時並行的に、発生する事象に対して引き起こされる状態遷移と、その遷移先の状態に紐づけられたアクション記述が実行されていく様子として表現されます。

状態モデルで定義された事象は、ユースケースのアクターのトリガーに相当するものとして考えてよいでしょう。
一般的なユースケース図では、複数の状態変化が同時並行的に進行していくような様を記述するのは難しいものですが、概念モデルと併用すれば、その様を記述できるだけでなく、デッドロックの発生や一貫性の破れ等を防止できます。

まとめ

以上、概念振舞モデルについて解説してきました。
これで、ソフトウェア開発の対象である現実世界を描写する為の最後のピースが出そろいました。
概念モデルをITシステムに組み込んで実装する方法は、本稿に続く、「概念モデルを IT システムに組み込む」で解説しているので継続して読破してください。
筆者の経験上、残念ながら、初見で概念モデリングを行うのは非常に難しいと言わざるを得ません。
初学者向けに、ドメインの定義から、概念モデリング、実装までを体験できる「チュートリアル」を提供しています。まずはそちらをお試しください。
コツをつかんだら、各自の身近で小さな問題に取り組んでみてください。


この記事が気に入ったらサポートをしてみませんか?