2026年3月31日火曜日

Cozyモデル駆動開発/ユースケース/generalize-realization

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

と関連しますが、具体的なアプローチを次回に取り上げる予定です。

2026年2月28日土曜日

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

Pieris Books(ブックカフェ併設のセレクトショップ販売店)のシステム開発プロジェクトを進めています。

要求モデルをCozyモデルとして定義する方法を検討しています。

現在はユースケース間の関係をCML(Cozy Modeling Language)でどのように記述するかという観点で整理を進めています。前回は extend を検討しました。

今回は generalize(汎化) を取り上げます。

generalize

  • マージモード : TypeRefinement
  • マージ点 : N/A(フロー非依存)
  • 機能 : 契約包含(仕様精緻化)
  • 由来 : UML generalization

generalizeの基本方針

Cozyモデルでは、ユースケース間のgeneralizationを

  • ユースケース間の型的関係(契約関係)

として定義します。

具体的なフロー継承方法やsuper展開規則は、generalizationの仕様外とします。

ユースケースの意味定義

Cozyモデルでは、ユースケースを

  • 状態遷移モデルの断片

とみなします。

その意味は、主に次の契約によって定義されます。

  • 事前条件(Pre)
  • 事後条件(Post)

ユースケース U は、

  • ある状態が Pre(U) を満たすとき実行可能であり
  • 実行後の状態は Post(U) を満たす

という仕様を持つものとします。

抽象状態機械は明示的には定義しませんが、

  • 暗黙の抽象状態機械 = ユースケース集合

という位置付けを取ります。

generalizationの定義

UseCase C が UseCase P を generalize するとは、

  • C が P の契約を包含し、意味を精緻化する関係

と定義します。

具体的には、LSP(リスコフの置換原則)的に次を満たすことを要件とします。

事前条件の包含

親の事前条件を満たす状態では、子も実行可能でなければならない。

すなわち、

  • C は P の事前条件を弱めない
  • 子は親より実行可能範囲を狭めてはならない

事後条件の保存

子は、親が保証する結果を壊してはならない。

  • C の事後条件は P の事後条件を包含するか、より強い保証を与える

直観的整理

  • 親が約束することは、子でも必ず成り立つ
  • 子は親より具体的であってよいが、意味を破壊してはならない

このとき、

  • generalization = 状態遷移断片の refinement(仕様精緻化)

とみなすことができます。

フローとの関係

前述した通りCozyモデルでは「generalizationはフローの継承方法を規定しない」というアプローチを取ります。

  • MainFlowは契約を実現するシナリオである
  • 契約が保持される限り、フロー構造は自由である

したがって、

  • super展開の位置
  • テンプレート的骨格継承
  • 差分オーバーライド

といったgeneralization関係にあるユースケース間のフローの関係は仕様としては定めておらず自由な構造を選択することができます。

include / extendとの違い

観点includeextendgeneralize
対象フロー構造フロー変形契約(意味)
本質構造合成条件付き拡張仕様精緻化
型関係なしなしあり
LSP制約なしなしあり

include や extend が

  • シナリオ構造の操作

であるのに対し、generalize は

  • 意味(契約)の包含関係

です。

記述例

usecase Purchase pre: - 顧客が商品を選択している post: - 注文が確定している - 支払いが登録されている

usecase PurchaseOnline generalize Purchase pre: - 顧客が商品を選択している - 顧客がログインしている post: - 注文が確定している - 支払いが登録されている - 配送先が登録されている

このとき、

  • 子は親の事前条件を包含し
  • 親の事後条件を壊していない

ため、generalization関係が成立します。

まとめ

本稿では、generalizeを

  • ユースケース間の型的関係 = 契約包含関係 = 状態遷移断片の精緻化

として定義しました。

generalizationは、

  • フロー構造の継承を規定するものではなく
  • 契約レベルでの意味関係を定義するもの

と位置付けます。

具体的なフロー実現方法(テンプレート的継承、差分オーバーライドなど)は、

  • generalizationを実現するための設計戦略

として、次回検討します。

2026年1月31日土曜日

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

Pieris Books(ブックカフェ併設のセレクトショップ販売店)のシステム開発のプロジェクトを進めています。

要求モデルをCozyモデルとして定義する方法について考えています。

ユースケース・モデルのユースケース・記述の基本情報と拡張情報の項目の洗い出しを行い、CML(Cozy Modeling Language)で記述する方法について考えました。

現在はユースケース間の関係のモデルについて、ユースケース間の関係のどのようにCMLで記述するか、という観点で具体的な記述方式を検討しています。前回はincludeの検討を行いました。

今回はextendを取り上げます。

extend

  • マージモード : Extend
  • マージ点 : 条件付きStep
  • 機能 : 例外的・追加的振る舞いの付与
  • UML extend

extendの意味

extendは、あるユースケースの実行中に、

  • 特定の条件が成立した場合にのみ
  • 追加の振る舞いが挿入される

ことを表す関係です。

UMLにおけるextendは、

  • 基本ユースケースの振る舞いを前提とし
  • 条件付きで拡張ユースケースが実行される

という意味を持ちます。

典型的な例としては、次のようなものがあります。

  • 「商品を購入する」を拡張する「クーポン適用」
  • 「会員登録」を拡張する「年齢確認」
  • 「注文処理」を拡張する「高額購入時の本人確認」

extendされる側のユースケースは、

  • 常に実行されるわけではなく
  • 基本ユースケースの一部を補足する

という性質を持ちます。

includeとの違い

includeとextendの違いを整理すると次のようになります。

観点includeextend
実行条件常に実行条件付き
主目的共通処理の再利用例外・オプションの追加
基本フロー前提独立して完結
位置づけ合成拡張

includeは「分解と再利用」、extendは「基本フローを壊さない条件付き拡張」と整理できます。

Cozyモデルにおけるextendの位置づけ

Cozyモデルでは、extendを

  • 図上の関係指定

ではなく、

  • ユースケース・シナリオ内における
  • 条件付きステップ合成

として扱います。

この観点からextendは、

  • 基本ユースケースを中心に据え
  • 例外や追加要件を独立したユースケースとして定義し
  • 条件に応じて合成する

ための仕組みと位置づけられます。

Cozyモデルにおけるextendは、

  • 条件付きでステップ列を合成する関係

として捉えることができます。

記述方式

シナリオ中のextendの記述方式は以下の通りです。

- extend <UseCaseName> when <Condition>
  • extendディレクティブで拡張であることを示します
  • when句で拡張が発生する条件を明示します

条件は、業務ルールや状態など、要求レベルで意味を持つ表現を用います。

記述例

- 顧客: 商品を選択する。
- 顧客: 支払い方法を指定する。
- extend ApplyCoupon when クーポンが指定されている
- 顧客: 注文を確定する。

この記述は、

  • ApplyCouponユースケースのMainFlowに定義された
  • ステップ列を
  • 「クーポンが指定されている」場合にのみ
  • この位置に合成する

ことを意味します。

基本フロー自体はクーポンを前提とせず、拡張として自然に切り出されています。

基本方針

CMLにおけるextendは、

  • 基本ユースケースの理解を妨げない
  • 例外やオプションを明示的に分離する

ことを重視します。

そのため、以下の方針を取ります。

  • extendは必ず条件を伴う
  • 基本ユースケースは単体で完結できる
  • 拡張ユースケースは意味的に独立した要求単位とする
  • マージ点をステップとして明示する

これにより、

  • 読めば分かる基本フロー
  • 必要に応じて追える拡張

という二層構造の要求モデルを実現します。

UML extendとの対応

UMLCozy / CML
extend関係条件付きステップ合成
拡張ポイントシナリオ内の明示的マージ点
条件when句
図表現テキストによる構造表現

UMLでは拡張ポイントという概念が図中に現れますが、Cozy/CMLではそれをステップ位置と条件として直接記述できます。

これにより、

  • 抽象的な関係指定に留まらず
  • 実行順・条件・意味を同時に表現できる

点が特徴です。

まとめ

今回は、ユースケース間の関係の一つであるextendについて、

  • UMLにおける意味
  • includeとの違い
  • Cozyモデルとしての解釈
  • CMLによる記述方針と具体例

を整理しました。

extendは、

  • 基本ユースケースを安定させたまま
  • 例外やオプション要求を切り出し
  • 条件付きで合成する

ための仕組みです。

includeとextendを使い分けることで、ユースケースの振る舞いを過不足なく・構造的に記述でき、図に依存しない、意味的に明確な要求モデルを構築できます。