2026年6月30日火曜日

Cozyモデル駆動開発/ユースケース/triggers

本稿では、ユースケース間の関係の一つである triggers(トリガ関係)を取り上げます。

triggersは、

  • あるユースケースの実行や状態変化をきっかけにする
  • 条件が成立した後に別のユースケースを起動する
  • 同期的な手順ではなく、イベント駆動の連携として表現する

ための関係です。

triggers

  • マージモード : EventDriven
  • マージ点 : After condition
  • 機能 : イベント駆動
  • 由来 :
    • Event-driven modeling
    • Domain event
    • Reactive system
    • Workflow event handling

triggersの基本方針

triggersは、

ユースケース間のイベント駆動の起動関係を定義する関係

です。

あるユースケースの途中または完了後に、特定の条件が成立したとき、その条件をイベントとして扱い、別のユースケースを起動することを表します。

precedesが「Aの後にBを行う」という順序関係であるのに対し、triggersは「Aによって発生した事実がBを起動する」という関係です。

したがってtriggersでは、

  • AとBを直列手順として密結合しない
  • Bの起動条件をイベントとして明示する
  • Bが同期的に起動されるか非同期に起動されるかは実行設計で決める

という整理になります。

シナリオ技術としてのtriggers

includeやextendがユースケース内部の構造を扱い、precedesがユースケース間の順序を扱うのに対し、triggersはユースケース間の反応関係を扱います。

例えば、Pieris Booksで次のような業務を考えます。

  • 注文が確定する
  • 在庫引当が必要になる
  • 顧客へ確認メールを送る
  • 配送準備を開始する

これらは「注文確定の後に必ず同じ手順で直列実行する処理」としても書けます。しかし、実際には注文確定という出来事を契機に、複数の後続処理がそれぞれ起動されると考えた方が自然な場合があります。

triggersは、このような

ある出来事に反応して別のユースケースが起動する構造

を表現します。

意味定義

UseCase A が UseCase B を triggers するとは、

A の実行中または完了後に条件 C が成立したとき、B の起動イベントが発生する

ことを意味します。

すなわち、

  • A の実行により事実や状態変化が発生する
  • その事実が条件 C を満たす
  • 条件 C の成立をイベントとして扱う
  • イベントによって B が起動候補になる

という流れになります。

ここで重要なのは、triggersが「Bを手続き的に呼び出す」関係ではないことです。

triggersは、

イベント発生とユースケース起動の関係

をモデル上で明示するための関係です。

直観的整理

  • triggersは「この出来事が起きたら、このユースケースが動く」という関係
  • 順序そのものではなく、起動条件を表現する
  • 後続処理をイベント駆動で分離する
  • 複数のユースケースが同じイベントに反応してもよい

契約との関係

triggersでは、起動元ユースケースの事後条件と、起動先ユースケースの事前条件の間に、イベント条件が入ります。

基本的には次のように整理できます。

  • A の実行により Event E が発生する
  • Event E が B の起動条件を満たす
  • B の Pre(B) が評価される
  • Pre(B) が成立すれば B が実行される

precedesでは Post(A) と Pre(B) の直接的な整合性が重要でした。一方triggersでは、

  • Post(A)
  • Event E
  • Pre(B)

の対応を整理することが重要になります。

望ましい条件は次の通りです。

  • Aの結果からイベントEが明確に導けること
  • イベントEがBの起動理由として妥当であること
  • Bの事前条件がイベントEまたは関連状態から満たせること

このためtriggersは、

  • ensures(事後条件)
  • requires(事前条件)
  • domain event

を結びつける関係として扱うことができます。

記述例

usecase ConfirmOrder pre: - 注文内容が入力されている - 支払い方法が選択されている post: - 注文が確定している - OrderConfirmed が発生している

usecase ReserveStock pre: - OrderConfirmed が発生している - 注文に在庫引当対象の商品が含まれている post: - 在庫が引き当てられている

usecase SendOrderConfirmation pre: - OrderConfirmed が発生している - 顧客の連絡先が登録されている post: - 注文確認通知が送信されている

usecase ConfirmOrder triggers ReserveStock when: - OrderConfirmed

usecase ConfirmOrder triggers SendOrderConfirmation when: - OrderConfirmed

このとき、

  • ConfirmOrder は ReserveStock を手続きとして直接呼び出しているわけではない
  • ConfirmOrder により OrderConfirmed というイベントが発生する
  • ReserveStock と SendOrderConfirmation は、そのイベントに反応して起動される

という関係になります。

precedesとの違い

triggersはprecedesと混同されやすい関係です。どちらもユースケース間の関係を扱いますが、意味は異なります。

観点precedestriggers
本質順序関係イベント駆動
マージモードSequenceEventDriven
マージ点After endAfter condition
起動理由前の処理が終わったから条件を満たすイベントが発生したから
結合度比較的強い比較的弱い
後続処理直列的反応的

precedesは、

Aが終わったらBへ進む

という関係です。

triggersは、

Aによってイベントが発生し、そのイベントにBが反応する

という関係です。

したがって、

  • 業務手順としてBがAの次に必ず必要なら precedes
  • Aの結果に反応してBが起動されるなら triggers
  • 同じイベントに複数の後続ユースケースが反応するなら triggers

と考えると分かりやすくなります。

他の関係との違い

観点includeextendprecedestriggers
対象フロー構造フロー変形実行順序起動条件
本質構造合成条件付き拡張シナリオ連結イベント駆動
時間関係なし部分あり条件成立後
結合内部合成内部拡張直列連結反応連携

includeは、共通フローをユースケース内部に埋め込みます。

extendは、条件付きでユースケース内部のフローを拡張します。

precedesは、ユースケース同士を時間順に接続します。

triggersは、イベントや条件を契機として別のユースケースを起動します。

つまりtriggersは、

フローの一部を共有するための関係ではなく、出来事に対する反応を表現する関係

です。

同期実行と非同期実行

triggersはイベント駆動の関係ですが、実装上の実行形態は一つに固定されません。

典型的には次の2つがあります。

  • 同期型 : イベント発生後、同じ処理の流れの中で起動先ユースケースを実行する
  • 非同期型 : イベントを発行し、別のタスクやワーカーが起動先ユースケースを実行する

モデル上のtriggersは、

何が何を起動するか

を表します。

一方で、同期か非同期かは、

  • 実行基盤
  • トランザクション境界
  • エラー処理
  • 再試行
  • 通知やキューの有無

といった設計で決めます。

この分離により、ユースケースモデルでは業務上の反応関係を表現し、実装設計では実行方式を選択できます。

設計上の注意点

triggersを使用する際は、次の点に注意します。

  • イベント名を業務上の事実として定義すること
  • 単なるメソッド呼び出しをtriggersとして表現しないこと
  • 起動条件を曖昧にしないこと
  • 同じイベントに反応するユースケースが増えすぎないようにすること
  • 同期実行と非同期実行の責務を混同しないこと

特に重要なのは、イベントを「命令」としてではなく「事実」として表現することです。

例えば、

  • ReserveStock

というイベント名にすると「在庫を引き当てよ」という命令に見えます。

一方、

  • OrderConfirmed

というイベント名にすると「注文が確定した」という事実になります。

triggersでは、この事実に対して後続ユースケースが反応する、という形にするとモデルが安定します。

まとめ

triggersは、

  • ユースケース間のイベント駆動の起動関係
  • 条件成立後に別のユースケースを起動する仕組み
  • 後続処理を直列手順から分離するための関係

です。

precedesが

時間的な連続性

を扱う関係であるのに対し、

triggersは

出来事に対する反応

を扱う関係です。

この関係を使うことで、

  • 注文確定後の在庫引当
  • 通知送信
  • 配送準備
  • 外部システム連携

のような処理を、ユースケース間のイベント駆動の連携として表現できます。