tactical-ddd について
リッチなドメインモデルのレビュー、設計、リファクタリングを支援する戦術的DDDスキルです。貧血モデルを検出し、DDDの構成要素を判断して、段階的な改善方法を示します。
主な機能
- 01貧血ドメインモデルの兆候検出
- 02エンティティ、値オブジェクト、集約、ドメインサービスの評価
- 03順序立てたリファクタリング
- 04不変条件と集約設計ルールの適用
- 05指摘事項の報告または変更前後の差分提示
活用シーン
- 01コード内の貧血ドメインモデルの確認
- 02ドメインクラスに適したDDD構成要素の選択
- 03setter中心のクラスを意図が明確な振る舞いへ改修
- 04境界とドメインイベントの設計
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ tech-leads-club/ agent-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 で参照する — 他の集約へのオブジェクト参照を保持しません
- まず値オブジェクトを使う — 個別の ID が不可欠な場合にのみエンティティを使います
- ドメインサービスは慎重に使う — サービスが多すぎると貧血モデルにつながります
- 不変条件を守る — 集約は最後の防衛線です。呼び出し元を決して信用してはいけません
出力形式
コードをレビューする場合、次を報告します。
## Anemia Diagnosis: <ClassName>
Severity: [None | Mild | Moderate | Severe]
Issues:
- <description of problem>
Recommended refactoring:
- <specific move from refactoring.md>
リファクタリングする場合、変更した各クラスについて変更前/変更後の差分を示します。
コメント
Markdown 対応