見出し画像

120. あらためて状態モデルの意義を語る

前回の記事

はじめに

前回まででコードジェネレータに潜んでいた障害はすべて排除しました。
あとは、生成されたコードの使い方を説明するのみですが、その前に状態モデルとデータフローベースのアクション記述について語ることにします。

状態モデル

このマガジンでは、
108. 世界は非同期で動いている|Knowledge & Experience
で、健診受診の概念ドメインにおける状態モデルの作成を披露しました。

状態モデルの基礎を今一度

概念モデリングにおいて、状態モデルは、圏Cのモデルである概念情報モデルに記述された、概念クラスに紐づけます。状態モデルを持つ概念クラスをひな型として存在する概念インスタンスは、その状態モデルをひな型とする状態機械が紐づけられます。概念インスタンスは、モデル化対象の意味の場を通じて観察している現実世界の圏Iの構成要素です。
圏C、圏I という用語については、

に詳しいので、もう一度読んでみてください。これまでの経験から、圏C、圏I の区別がつかない人が多いという印象があるので、ダメ押しです。

概念インスタンスは状態モデルで記述されたどれか一つの状態にいます。事象による遷移が発生すると、遷移先の状態に紐づいたエントリアクションが実行されます。エントリアクションの実行中、圏Iの状態変化が起こります。”圏Iの状態変化”の”状態”は、状態モデルの状態ではなく、圏Iの概念インスタンスの生成消滅、特徴値の更新、リンクの生成消滅のことを指すことに注意してください。圏Iの状態は、状態機械の状態遷移が確定した時点で、圏Cで記述された制約(リレーションシップの多重度など)に従わなければなりませんが、エントリアクション実行中は、圏C の制約が破れていてもかまいません。

現実世界の写しとしての状態モデル

こんな風に書いてくると、理屈が多すぎて、グリコ状態になる読者が大野ではないでしょうか。苦笑)
現実の世界の様を頭に思い浮かべてみましょう。ちょっと哲学的な話になってしまうかもしれませんが、我々が認識している現実世界は、各時々々でのスナップショットに過ぎません。そのスナップショットを記述したモデルが圏Iのモデルであるということになります。時間経過も含め、何らかの事象が発生すると現実世界に変化が起きます。”状態モデルの状態”と”圏Iの状態”、どちらも”状態”という言葉で紛らわしいので、以下、”圏Iの状態”のほうをを”圏Iの状況”と書くことにします。
状況”=”圏Cの制約に従って存在する、値が確定した特徴値が紐づいた概念インスタンス群とそれらの間の意味的リンク”であることをお忘れなく。
現実世界の変化を記述するためには、少なくとも、変化前の状況と変化後の状況の記述が必要です。ある時点から次の時点まで何も起こらなければ変化前の状況と変化後の状況は同一なのは、言うまでもありません。状況に変化があるならば、何らかの事象が発生し、それに伴い、圏Iを構成する要素に変化があったということです。現実世界においては、事象の発生、それに伴う構成要素、つまり、状況の変化は、複数箇所で同時並行的に起きえます。変化する現実世界の主体に対応するモデル上の要素は概念インスタンスなので、各事象を受けるのは、どれか一つの概念インスタンスであると考えるのは記述方法として自然でしょう。また、事象によって引き起こされる状況の変化が一段落した時点を、概念インスタンスの状態として記述し、事象発生前の状態から、事象発生により、一段落した時点の状態に遷移が発生したと記述することも自然でしょう。その状態遷移の間には、状況の変化が存在します。どんなふうに状況が変化したか、その流れを、概念モデリングとはアクションと呼んでいます。その変化の過程で何が起こったかを明らかにするための記述=モデル化も、当然必要です。そのモデル化のことをアクション記述と呼ぶわけです。アクションは、ある状態から新しい状態への遷移の過程でアクションが実行される、つまり、新しい状態が確定するまでにその実行が完了するような記述(モデル)であれば、現実世界を記述する自然な方法といえます。モデルとして記述する際、アクションは遷移の過程に紐づけられることになりますが、

  • 変化前の状態の出口(Exit)

  • 遷移

  • 変化後の状態の入口(Enter)

のどれかが候補です。注目するべき認識対象の観点は、遷移後の状況にあるので、アクションを遷移先の状態に紐づけて記述することに問題はないでしょう。
UML(Unified Modeling Language)では、状態モデルを記述するときのアクションを紐づけは、上の3つ全てとしています。しかし、実際に状態モデルを作ってみると、3つ全てのアクションが紐づけられているような状態モデルは非常に複雑で、正しさの検証が半端なく難しいモデルになっています。概念モデリングでそうしているように、アクションは遷移先の状態のエントリアクションに紐づけるのが実用的です。

詳しくは、7. 現実世界のダイナミクスと概念振舞モデルに関する考察|Knowledge & Experience を読んでみてください。

現実世界の競合を調停する

通常のビジネスでありがちな、

  1. お客様からの注文をもとに注文伝票を作成する

  2. 在庫から商品を引き当てて、在庫情報を更新する

  3. 配送伝票を作成する

  4. 配送伝票に従って、配送を手配する

というフローを考えてみます。これらは別々の部門(担当者)が担当するものとします。
一番目の処理の途中で、注文伝票の品数の記入途中で、気の早い在庫管理担当者が、注文伝票を横から覗き見て、二番目の処理を開始したとします。注文伝票の作成担当者は、品数の項目に”12”と書こうとしていたのに、”1”と書いた時点で在庫管理担当者が作業を開始してしまったら、この注文処理はどうなってしまうでしょう。当然のことながら、発注ミスが生じてしまいます。お客様から”注文を受けつけた”という事象の発生による状態遷移において、”注文伝票作成完了”という状態確定まで、在庫管理担当者は待たなければなりません。”注文伝票の作成が完了した”ことを新たな事象発生ととらえて、在庫管理担当者の状態機械がその事象を受け取るような状態モデルとして記述することでこの様を自然に記述することが可能です。

1番目、2番目と文章として上から下に並べて書くと、特に問題はないようですが、注文受付担当者が複数人働いていた場合は、この流れがその人数分だけ、同時並行的に生じることになり、中途半端な品数記述で起こったのと同様な問題が、2番目の在庫引き当ての過程で生じてしまう可能性があります。平たく言えば、十分な在庫が無いのに、配送処理が開始されてしまった、ということ。
詳しくは、4. 概念振舞モデル|Knowledge & Experience の”競合と割当てパターン”を読んでほしいのですが、状態モデルを使うことにより、競合問題が生じないような記述が可能です。

実際のビジネスフローの中には、実は、こんな不具合が各所に潜んでいるのではないでしょうか。概念モデリングの体系を使って、現状のビジネスをモデル化すれば、そんな不具合を発見することができます。

通常のソフトウェア開発の流れにおいては、このような競合を具体的に解決する手段は、プログラミングの工程でなされるのが一般的でしょう。解決する手段としては、ソフトウェア実行プラットフォームが規定する排他機構を使ったマルチスレッドプログラミングの技が駆使されることと思われます。しかし、このようなやり方では、ビジネスプロセス本来の問題とソフトウェア実装上の問題が混在した解決策になってしまいます。ビジネスプロセス側のフローをちょっと変えれば、複雑なプログラミングテクニックを駆使しなくてもよかったかもしれないのに、です。
概念モデリング×変換による実装では、

ここから先は

783字

2022年3月にマイクロソフトの中の人から外の人になった Embedded D. George が、現時点で持っている知識に加えて、頻繁に…

この記事が気に入ったらチップで応援してみませんか?