refactoring-best-practices について
既存コードを安全に変更する開発者向けのスキルです。動作の保護とフィードバックを先行させ、実際の課題に沿って小さく可逆的に変更します。
主な機能
- 01現状の動作を観察して記録
- 02特性テストでフィードバックを追加
- 03リスクの高い依存関係を隔離
- 04責務ごとに段階的に変更
- 05レガシーコード変更の参考資料
活用シーン
- 01テストのないコードのリファクタリング開始
- 02インフラ依存関係を境界の内側に隔離
- 03大きなサービスを段階的に分割
- 04永続データやエラー契約の移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ luckys/ agent-skills --skill refactoring-best-practicesインストール後、Claude Code で/refactoring-best-practicesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/characterization-tests.mdcode-smells.mdcompatibility-and-migration.mddomain-event-migration.mderror-contract-migration.mdfran-iglesias-refactoring-guidance.mdlanguage-examples.mdlegacy-code-techniques.mdrefactoring-moves.mdsafe-change-workflow.mdthird-party-notices.md詳細
リファクタリングのベストプラクティス
既存のコードを安全に変更することが主な課題である場合は、このスキルを使用してください。
作業スタイル
- 設計を改善する前に、動作を保護します。
- 大胆な書き換えより、小さく元に戻せる変更を優先します。
- 抽象化を加える前に、フィードバックを得られるようにします。
- 一度に変更する責務は一つにします。
- 次の変更は、現在の問題点に基づいて決めます。
安全なリファクタリングのワークフロー
-
現在の動作を確認します。
- 出力、副作用、エラー経路を特定します。
- 変更してはならないものを特定します。
-
フィードバックを得られるようにします。
- 目に見える動作を対象とする特性テストを優先します。
- テストだけでは不十分な場合に限り、ログや一時的な調査用コードを追加します。
-
境界を見つけます。
- 時刻、ファイルシステム、ネットワーク、フレームワークのグローバル要素、シングルトン、外部 API を切り離します。
- リスクのある依存関係を囲む、可能な限り狭い境界を作ります。
-
次の変更を選びます。
- メソッドの抽出
- クラスの抽出
- 値オブジェクトの導入
- ファーストクラスコレクションの導入
- メソッドの移動
- 条件分岐をポリモーフィズムに置き換える
- 構築と動作を分離する
- ドメインイベントと二次サブスクライバーを一つずつ抽出する
-
意味のある変更を行うたびに、フィードバックを再確認します。
効果の高いリファクタリング手法
- まとまりのあるドメインパラメーター群は値オブジェクトに置き換えます。共通するドメイン上の意味や不変条件がない場合は、パラメーターオブジェクトを使用します。
- 大規模なサービスを、役割に特化した協調オブジェクトに分割します。
- ビジネスルールをコントローラー、スクリプト、ユーティリティクラスから移します。
- 型コードや不安定な条件分岐を、明示的な役割に置き換えます。
- インフラストラクチャをポートまたはアダプターの背後に置きます。
- 異なる理由で変更されるメソッド群がある場合は、クラスを分割します。
危険信号
- 一度にすべてを書き換えること。
- 動作の基準が保護されていない状態で、新たな抽象化を導入すること。
- より明確なモデルを作らず、コードを小さなクラスに分割すること。
- テストを容易にすることだけを目的に、継承を導入すること。
- リスクを無視して、見た目だけを理由にリファクタリングすること。
判断基準
今すぐリファクタリングする場合
- 同じ知識が複数の場所に重複している
- コードが実際の変更を妨げている
- 次の機能追加によって、結合や重複がさらに深刻になる
- 現在の構造では欠陥が発生しやすい
待つ場合
- まだフィードバックループがない
- 問題が仮定上のものにすぎない
- 抽象化がまだ安定しておらず、新しい型を導入する段階ではない
- 変更範囲は広いが、理解がまだ不十分である
参考資料
-
呼び出し元の変更、レガシー経路の削除、または永続化された表現の移行を行う場合は、
references/compatibility-and-migration.mdを読んでください。 -
境界に基づくリファクタリング、検知と分離、レガシーコード変更アルゴリズムについては、
references/safe-change-workflow.mdを読んでください。 -
段階的な値オブジェクト移行手順を含む具体的な変更手法と、その使い分けについては、
references/refactoring-moves.mdを読んでください。 -
問題の見極め、設計上の根拠としての時間的な同時変更、適切な手法の選択については、
references/code-smells.mdを読んでください。 -
テストなしで作業するための Sprout、Wrap、Extract and Override などの手法については、
references/legacy-code-techniques.mdを読んでください。 -
テストされていないコードをリファクタリングする前にテストを書く方法については、
references/characterization-tests.mdを読んでください。 -
レガシーな副作用をイベント/サブスクライバーへ段階的に移行し、失敗時のセマンティクスや確実な引き渡しを維持する方法、および移行の橋渡しとしての CDC については、
references/domain-event-migration.mdを読んでください。 -
失敗のタイミング、診断情報、秘匿化、公開契約を維持しながら、null、文字列、汎用例外を安全に置き換える方法については、
references/error-contract-migration.mdを読んでください。 -
Fran Iglesias の知見をまとめた、実践的なリファクタリングのヒューリスティクスについては、
references/fran-iglesias-refactoring-guidance.mdを読んでください。 -
複数の言語による変更前/変更後のスタイル例については、
references/language-examples.mdを読んでください。
関連スキル
- 日常的な新規コードの判断には、
oop-best-practicesを使用します。 - 主な課題がオブジェクト間の協調パターンの選択である場合は、
design-patterns-best-practicesを使用します。 - 不変条件の移動、肥大化したAggregateの分割、ルートの導入、一貫性境界の変更、またはレガシーな永続化処理から抽出したドメインRepositoryの設計には、
ddd-best-practicesを使用します。 - 永続化データの移行やバックフィルには、
data-migration-best-practicesを使用します。このスキルが扱うのは、その運用上の移行を支える安全なコードの接続点と互換性の維持経路のみです。
参考にした資料
このスキルは、以下で重視されている考え方をまとめたものです。
- Michael Feathers著『Working Effectively with Legacy Code』
- Sandi Metz著『99 Bottles of OOP』
- Sandi Metz著『Practical Object-Oriented Design in Ruby』
- Fran Iglesiasの「Object Calisthenics」シリーズ
- CodelyTV Aggregates course(時間的結合とAggregateの進化)
- CodelyTV Value Objects course(プリミティブ値からドメイン値への段階的なリファクタリング)
- CodelyTV Repository Pattern course(直接的なSQL処理からポートへの段階的なリファクタリング)
- CodelyTV Domain Events course(レガシーコードにおけるイベントの接続点とCDCの反例)
- CodelyTV Domain Modeling Errors course(例外からResultへの段階的な移行と境界コントラクトに関する教訓)
- CodelyTV Four Rules of Simple Design course(動作を維持するテスト、推測に基づく要素の削除、重複に関する反例)