tactical-ddd について
tactical-dddは、リッチなドメインモデルを目指すコードレビューとリファクタリングのためのコーディングスキルです。貧血モデルの兆候を検出してDDDの構成要素を提案し、レビューでは変更前に所見を示して承認を求めます。
主な機能
- 01貧血モデルの兆候を検出
- 02DDDの構成要素を評価
- 03順序立てたリファクタリング手順
- 04レビューとコード変更を分離
- 05レビュー出力形式を提示
活用シーン
- 01クラスの貧血モデルパターンを確認
- 02エンティティ、値オブジェクト、集約を選定
- 03サービスロジックをドメインモデルへ移す
- 04設計上の問いからドメインモデルを検討
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ marcioaltoe/ skills --skill tactical-dddインストール後、Claude Code で/tactical-dddを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
detection.mdrefactoring.mdreference.md詳細
戦術的 DDD — リッチドメインモデリング
ワークフロー
まず、ユーザーの意図を判断します。
| 意図 | 実行するフェーズ |
|---|---|
| 「検証/レビュー/確認/これで正しいですか?」 | フェーズ 1 + 2 のみ → 所見を報告し、リファクタリングの前に確認する |
| 「修正/リファクタリング/改善/整理」 | フェーズ 1 + 2 + 3 |
| 「どう設計/モデリングすればよいですか?」 | reference.md を直接読み込む |
フェーズ 1 — 検出
detection.md を読み込み、対象コードをスキャンして貧血モデルの兆候を確認します。深刻度スコアと影響を受けるクラスの一覧を作成します。
フェーズ 2 — 評価
影響を受ける各クラスについて、適切な構成要素を判断します。
| 一意の ID があり、時間を通じて追跡されるか? | 複数のオブジェクトにまたがる不変条件があるか? | → 構成要素 |
|---|---|---|
| はい | — | エンティティ |
| いいえ | — | 値オブジェクト |
| はい(ルート)+ 共有不変条件を持つ子 | はい | 集約 |
| 複数の集約にまたがる/どの集約にも属さない操作 | — | ドメインサービス |
エンティティより値オブジェクトを優先します。大きな集約より小さな集約を優先します。
意図が検証/レビューの場合:ここで終了します。以下の出力形式で所見を報告します。続行する前に「これらの修正を適用しますか?」と確認します。
フェーズ 3 — リファクタリング
refactoring.md を読み込み、手順に沿って変更します。次の順序で適用します。
- セッターの連鎖を、表現力のある単一のメソッドに置き換える
- サービスのロジックを、それを所有する集約に移す
- 各メソッドの先頭にビジネス上のガードを追加する
- 状態変更が成功するたびにドメインイベントを発行する
- プリミティブ型を値オブジェクトに置き換える
パターンに関する詳しい質問(境界の設計、イベントのモデリング、サービスとエンティティの判断)には、reference.md を読み込みます。
貧血モデルの主な兆候(まずスキャン)
public setX() / public setY() → behaviour should be encapsulated
service.doX(entity, ...) → logic likely belongs in entity
entity.setA(); entity.setB(); ... → setter chain = missing intent method
no domain methods beyond getters → pure data bag
基本原則
- 振る舞いとデータを一体化する — オブジェクトは状態と、その状態を変更する操作の両方を所有します
- ユビキタス言語 — メソッド名は CRUD ではなく、ドメインに由来します(
setStatusではなくcommitTo) - 小さな集約 — 既定ではルート + 値オブジェクトとし、真に不変条件が必要な場合にのみ子エンティティを追加します
- 1 つのトランザクション = 1 つの集約 — 集約をまたぐルールには、ドメインイベントを介した結果整合性を使用します
- ID で参照する — 他の集約へのオブジェクト参照を保持してはいけません
- まず値オブジェクトを使う — 個別の同一性が不可欠な場合にのみエンティティを使用します
- ドメインサービスは控えめに使う — サービスが多すぎると貧血モデルになります
- 不変条件を保護する — 集約は最後の防衛線です。呼び出し元を決して信用してはいけません
出力形式
コードをレビューする場合は、次の内容を報告します。
## Anemia Diagnosis: <ClassName>
Severity: [None | Mild | Moderate | Severe]
Issues:
- <description of problem>
Recommended refactoring:
- <specific move from refactoring.md>
リファクタリングする場合は、変更したクラスごとに変更前/変更後の差分を示します。
コメント
Markdown 対応