Pieris Books(ブックカフェ併設のセレクトショップ販売店)のシステム開発プロジェクトを進めています。
前回は、ユースケース間の generalize(汎化)を
- 契約(Pre/Post)の包含関係
- 状態遷移断片の精緻化
として定義しました。
本稿では、その generalization をどのように実現するか、すなわち「フロー設計の戦略」について整理します。
本稿の位置づけ
前回:
- generalize = 契約関係(型)
本稿:
- generalize を満たすための実現戦略(設計パターン)
つまり、重要な前提として、
- generalizationはフローを規定しない
- しかしフローは契約を満たさなければならない
という関係にあります。この実装戦略が本稿のテーマです。
generalizationの実現戦略
generalizationは「意味の包含」であり、フローはその実現手段です。
そのため、複数の実現パターンが存在します。
本稿では代表的な3つを整理します。
- Template型
- Extension型
- Replacement型
Template型(骨格共有)
- 親ユースケースがフローの骨格を提供し、子ユースケースが一部のステップを差し替える方式
これはいわゆる Template Method に相当します。
特徴
- フローの構造は親が支配する
- 子は差分のみを定義する
- 契約との対応が明確
適用場面
- 処理手順がほぼ同じ
- 一部の処理だけ差し替えたい
例
- Purchase の中の「支払い処理」を差し替える
- PurchaseOnline / PurchaseInStore の分岐
評価
- 一貫性が高い
- 再利用性が高い
- ただし柔軟性は低い
Extension型(後付け拡張)
- 親ユースケースのフローをベースとし、子が追加ステップを挿入する方式
extendに近いが、契約レベルで整合している点が異なります。
特徴
- 親のフローをベースにする
- 子は追加責務を持つ
- 契約は強化される
適用場面
- 追加機能(ログ、通知、配送など)
- オプション的な振る舞い
例
- Purchase に対して配送登録を追加する PurchaseOnline
評価
- 柔軟性が高い
- ただしフローの一貫性は弱くなりやすい
Replacement型(全面再定義)
- 子ユースケースがフローを完全に再定義する方式
契約だけを共有し、実装は独立します。
特徴
- フローは完全に独立
- 契約のみ共通
- 最も自由度が高い
適用場面
- 実現方式が大きく異なる
- UIやチャネルが異なる(オンライン / 店頭など)
例
- Purchase と PurchaseOnline が全く異なる手順で実行される
評価
- 柔軟性が最大
- 再利用性は低い
- 設計の一貫性維持が難しい
3つの戦略の整理
| 観点 | Template型 | Extension型 | Replacement型 |
|---|---|---|---|
| フロー共有 | 高い | 中程度 | なし |
| 柔軟性 | 低い | 中 | 高い |
| 契約整合 | 明確 | 明確 | 明確 |
| 再利用性 | 高い | 中 | 低い |
重要なのは、
- どの方式でも generalizationの契約制約は守られる必要がある
という点です。
まとめ
generalizationは
- 契約の関係
であり、
その実現は
- フロー設計の戦略
として分離されます。
この分離により、
- 型安全な意味定義
- 柔軟な実行設計
を両立することができます。
- Template型をDSLとしてどう表現するか
- 差分記述(override)の記法設計
- フロー合成の形式化
といった点は、
- aggregatebehavior や内部DSL
と関連しますが、具体的なアプローチを次回に取り上げる予定です。
