ddd-refactor について
既存コードを DDD に近づけるリファクタリング手法です。コードの問題点と目標パターンを特定し、振る舞いを保つ小さな変更手順を組み立てます。方針が決まっている開発者向けです。
主な機能
- 01コードの問題点を目標パターンに対応
- 02振る舞いを保つ小さな変更を計画
- 03代表的な DDD 改修手順を提示
- 04各段階でのテストとコミットを推奨
活用シーン
- 01貧血モデルを振る舞いを持つエンティティに変更
- 02プリミティブ型を値オブジェクトに置換
- 03大きすぎる集約を分割
- 04境界づけられたコンテキストを段階的に導入
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yonatankarp/ software-design-skills --skill ddd-refactorインストール後、Claude Code で/ddd-refactorを入力して読み込まれたか確認します。
詳細
1 行の概要
DDD に向けたリファクタリングを順序立てて進めます。問題点を特定し、目指すパターンに名前を付け、動作を保つ小さな手順を順に提案します。
このスキルを使う場面
- ユーザーがすでに問題だと考えている既存コード。
- ユーザーがリファクタリングのおおよその方向性を把握している。
- レガシーモジュールを DDD モデルへ移行する場合。
このスキルを使わない場面
- ユーザーがレビューだけを求めていて、まだリファクタリングに取り組む準備ができていない場合 →
ddd-reviewに案内します。 - ユーザーが新しいドメインモデルをゼロから作成する場合 →
ddd-designに案内します。
主な内容
一般的なパターンは、問題点に名前を付け、目指す形に名前を付け、動作を保つ小さな手順を書き出し、各手順の間にテストを実行して、手順ごとにコミットすることです。
よくあるリファクタリングと手順:
貧血モデル → 振る舞いを持つエンティティ。 (1) 現在サービスで実行されている操作を 1 つ選びます。(2) 同じシグネチャを保ったまま、その操作をエンティティに移します。(3) サービスから新しいエンティティメソッドに処理を委譲します。(4) 呼び出し元がそれだけなら、サービス呼び出しをインライン化します。操作ごとに繰り返します。
プリミティブ型への執着 → 値オブジェクト。 (1) プライベートコンストラクターと検証を行うファクトリーを備えた、新しい値オブジェクト型を導入します。(2) 境界(入力の解析)に変換箇所を 1 つ追加します。(3) 最も深い箇所から、1 つずつ置き換えます。(4) 公開 API でプリミティブ型を受け付けないようにします。ddd-value-object を参照してください。
巨大な集約 → 複数の集約。 (1) 現在その中にあるエンティティを一覧にします。(2) それぞれのペアについて「これらは同じトランザクション内で変更する必要があるか?」と問い、はいと答えたものをグループ化します。(3) 各グループのルートを特定します。(4) グループ間のオブジェクト参照を ID 参照に置き換えます。(5) グループ間の整合性をイベントに移します。ddd-aggregate を参照してください。
漏洩するリポジトリ → ドメインリポジトリインターフェース。 (1) ユビキタス言語に基づいた名前のメソッドを持つ、ドメイン層のインターフェースを定義します。(2) 既存の永続化処理をラップする形で、インフラ層に実装します。(3) 呼び出し元を 1 つずつ切り替えます。(4) 漏洩した型をドメイン層から削除します。ddd-repository を参照してください。
泥団子 → 最初の境界づけられたコンテキスト。 (1) 最も問題の大きい境界を選びます。(2) 意図する境界を紙に描きます。(3) その境界に腐敗防止層を導入します。(4) 型を 1 つずつ境界の向こう側へ移します。その境界に適したパターンについては、ddd-context-mapping を参照してください。
判断の指針
- リファクタリングのコミットと機能追加のコミットを決してまとめないでください。レビューも個別に行い、取り消しも個別に行います。
- 各手順で動作を同一に保つ必要があります。テストスイートは安全策です。まだない場合は、まず特性テストを書いてください。
- 各手順の後、テストを実行してコミットするまで、次に進まないでください。
- 一括書き換えはユーザーの信頼を損ない、ほぼ必ず作業範囲が拡大します。大規模なリファクタリングを 1 回行うより、小さなリファクタリングを 10 回行う方を選んでください。
アンチパターン
- 段階的なマイルストーンを設けずに一括で書き換える。
- テストによる安全網なしにリファクタリングする。
- 構造や責務を変えず、クラス名を「DDD らしく」するためだけに変更する。
- 同じ変更でリファクタリングと機能追加を行う。
関連項目
ddd-anti-patterns— 各リファクタリングのきっかけとなる問題点。ddd-aggregate、ddd-value-object、ddd-bounded-context、ddd-repository— 目指す形。ddd-deeper-insight— 明白なリファクタリングを終えた後に行うこと。
参考文献
- Evans、『Domain-Driven Design』(2003 年)、第 III 部(第 8~13 章)。