本稿では、ユースケース間の関係の一つである 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と混同されやすい関係です。どちらもユースケース間の関係を扱いますが、意味は異なります。
| 観点 | precedes | triggers |
|---|---|---|
| 本質 | 順序関係 | イベント駆動 |
| マージモード | Sequence | EventDriven |
| マージ点 | After end | After condition |
| 起動理由 | 前の処理が終わったから | 条件を満たすイベントが発生したから |
| 結合度 | 比較的強い | 比較的弱い |
| 後続処理 | 直列的 | 反応的 |
precedesは、
Aが終わったらBへ進む
という関係です。
triggersは、
Aによってイベントが発生し、そのイベントにBが反応する
という関係です。
したがって、
- 業務手順としてBがAの次に必ず必要なら precedes
- Aの結果に反応してBが起動されるなら triggers
- 同じイベントに複数の後続ユースケースが反応するなら triggers
と考えると分かりやすくなります。
他の関係との違い
| 観点 | include | extend | precedes | triggers |
|---|---|---|---|---|
| 対象 | フロー構造 | フロー変形 | 実行順序 | 起動条件 |
| 本質 | 構造合成 | 条件付き拡張 | シナリオ連結 | イベント駆動 |
| 時間関係 | なし | 部分 | あり | 条件成立後 |
| 結合 | 内部合成 | 内部拡張 | 直列連結 | 反応連携 |
includeは、共通フローをユースケース内部に埋め込みます。
extendは、条件付きでユースケース内部のフローを拡張します。
precedesは、ユースケース同士を時間順に接続します。
triggersは、イベントや条件を契機として別のユースケースを起動します。
つまりtriggersは、
フローの一部を共有するための関係ではなく、出来事に対する反応を表現する関係
です。
同期実行と非同期実行
triggersはイベント駆動の関係ですが、実装上の実行形態は一つに固定されません。
典型的には次の2つがあります。
- 同期型 : イベント発生後、同じ処理の流れの中で起動先ユースケースを実行する
- 非同期型 : イベントを発行し、別のタスクやワーカーが起動先ユースケースを実行する
モデル上のtriggersは、
何が何を起動するか
を表します。
一方で、同期か非同期かは、
- 実行基盤
- トランザクション境界
- エラー処理
- 再試行
- 通知やキューの有無
といった設計で決めます。
この分離により、ユースケースモデルでは業務上の反応関係を表現し、実装設計では実行方式を選択できます。
設計上の注意点
triggersを使用する際は、次の点に注意します。
- イベント名を業務上の事実として定義すること
- 単なるメソッド呼び出しをtriggersとして表現しないこと
- 起動条件を曖昧にしないこと
- 同じイベントに反応するユースケースが増えすぎないようにすること
- 同期実行と非同期実行の責務を混同しないこと
特に重要なのは、イベントを「命令」としてではなく「事実」として表現することです。
例えば、
- ReserveStock
というイベント名にすると「在庫を引き当てよ」という命令に見えます。
一方、
- OrderConfirmed
というイベント名にすると「注文が確定した」という事実になります。
triggersでは、この事実に対して後続ユースケースが反応する、という形にするとモデルが安定します。
まとめ
triggersは、
- ユースケース間のイベント駆動の起動関係
- 条件成立後に別のユースケースを起動する仕組み
- 後続処理を直列手順から分離するための関係
です。
precedesが
時間的な連続性
を扱う関係であるのに対し、
triggersは
出来事に対する反応
を扱う関係です。
この関係を使うことで、
- 注文確定後の在庫引当
- 通知送信
- 配送準備
- 外部システム連携
のような処理を、ユースケース間のイベント駆動の連携として表現できます。

0 件のコメント:
コメントを投稿