- Translate all 101 markdown files: P1 core, all 10 modules, examples, auxiliary docs (CONTRIBUTING, CODE_OF_CONDUCT, SECURITY, CLAUDE.md, etc.), peripheral docs (.github/, docs/, resources/, scripts/) - Translate comments and user-facing messages in 06-hooks/*.sh examples - Copy 05-mcp/*.json examples (standard JSON, no comments) - Update root README.md language switcher to include 日本語 - Add ja/TRANSLATION_NOTES.md (glossary + style guide) All translations pass pre-commit quality gates (markdown-lint, cross-references, mermaid-syntax, link-check, build-epub).
430 lines
15 KiB
Markdown
430 lines
15 KiB
Markdown
<!-- i18n-source: 03-skills/refactor/SKILL.md -->
|
||
<!-- i18n-source-sha: 245272f -->
|
||
<!-- i18n-date: 2026-04-27 -->
|
||
---
|
||
name: code-refactor
|
||
description: Martin Fowler の方法論に基づく体系的なコードリファクタリング。ユーザーがコードのリファクタリング、コード構造の改善、技術的負債の削減、レガシーコードのクリーンアップ、コードスメルの解消、コード保守性の向上を求めた際に使用する。本スキルは、リサーチ・計画・安全な段階的実装からなる段階的アプローチを案内する。
|
||
---
|
||
|
||
# コードリファクタリングスキル
|
||
|
||
Martin Fowler 著『Refactoring: Improving the Design of Existing Code』(第 2 版) に基づくコードリファクタリングへの体系的アプローチ。本スキルは、テストに支えられた安全で段階的な変更を重視する。
|
||
|
||
> "Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure." — Martin Fowler
|
||
|
||
## 中核となる原則
|
||
|
||
1. **振る舞いの保全**: 外部から見える振る舞いは変えてはならない
|
||
2. **小さなステップ**: テスト可能な微小な変更を積み重ねる
|
||
3. **テスト駆動**: テストはセーフティネットである
|
||
4. **継続的**: リファクタリングは一度きりの作業ではなく継続的に行う
|
||
5. **協調的**: 各フェーズでユーザーの承認が必要
|
||
|
||
## ワークフロー概要
|
||
|
||
```
|
||
Phase 1: Research & Analysis
|
||
↓
|
||
Phase 2: Test Coverage Assessment
|
||
↓
|
||
Phase 3: Code Smell Identification
|
||
↓
|
||
Phase 4: Refactoring Plan Creation
|
||
↓
|
||
Phase 5: Incremental Implementation
|
||
↓
|
||
Phase 6: Review & Iteration
|
||
```
|
||
|
||
---
|
||
|
||
## フェーズ 1: リサーチと分析
|
||
|
||
### 目的
|
||
- コードベースの構造と目的を把握する
|
||
- リファクタリングの範囲を特定する
|
||
- ビジネス要件に関するコンテキストを収集する
|
||
|
||
### ユーザーへの確認事項
|
||
開始前に次の点を明確化する。
|
||
|
||
1. **範囲**: どのファイル/モジュール/関数をリファクタリングするのか?
|
||
2. **目標**: 何を解決したいのか?(可読性、性能、保守性)
|
||
3. **制約**: 変更してはいけない領域はあるか?
|
||
4. **時間的圧力**: 他作業のブロッカーになっているか?
|
||
5. **テスト状況**: テストは存在するか?パスしているか?
|
||
|
||
### アクション
|
||
- [ ] 対象コードを読み、理解する
|
||
- [ ] 依存関係と統合箇所を洗い出す
|
||
- [ ] 現行アーキテクチャを文書化する
|
||
- [ ] 既存の技術的負債マーカー(TODO、FIXME)を控える
|
||
|
||
### 出力
|
||
ユーザーへの提示内容:
|
||
- コード構造のサマリー
|
||
- 検出された問題箇所
|
||
- 初期推奨事項
|
||
- **着手の承認を依頼する**
|
||
|
||
---
|
||
|
||
## フェーズ 2: テストカバレッジの評価
|
||
|
||
### なぜテストが重要か
|
||
> "Refactoring without tests is like driving without a seatbelt." — Martin Fowler
|
||
|
||
テストは安全なリファクタリングを可能にする**鍵となる要素**である。テストがなければ、バグを混入させるリスクがある。
|
||
|
||
### 評価ステップ
|
||
|
||
1. **既存テストの確認**
|
||
```bash
|
||
# テストファイルを探す
|
||
find . -name "*test*" -o -name "*spec*" | head -20
|
||
```
|
||
|
||
2. **既存テストの実行**
|
||
```bash
|
||
# JavaScript/TypeScript
|
||
npm test
|
||
|
||
# Python
|
||
pytest -v
|
||
|
||
# Java
|
||
mvn test
|
||
```
|
||
|
||
3. **カバレッジの確認(可能な場合)**
|
||
```bash
|
||
# JavaScript
|
||
npm run test:coverage
|
||
|
||
# Python
|
||
pytest --cov=.
|
||
```
|
||
|
||
### 判断ポイント: ユーザーへの確認
|
||
|
||
**テストが存在し、かつパスしている場合:**
|
||
- フェーズ 3 へ進む
|
||
|
||
**テストが不足、または不完全な場合:**
|
||
次の選択肢を提示する。
|
||
1. 先にテストを書く(推奨)
|
||
2. リファクタリング中に段階的にテストを追加する
|
||
3. テストなしで進める(リスクあり、ユーザーの明示的同意が必要)
|
||
|
||
**テストが失敗している場合:**
|
||
- STOP。リファクタリング前に失敗テストを修正する
|
||
- ユーザーに確認: 先にテストを直すべきか?
|
||
|
||
### テスト作成のガイドライン(必要時)
|
||
|
||
リファクタリング対象の各関数について、以下をテストでカバーする。
|
||
- ハッピーパス(通常動作)
|
||
- エッジケース(空入力、null、境界値)
|
||
- エラーシナリオ(無効入力、例外)
|
||
|
||
「red-green-refactor」サイクルを用いる。
|
||
1. 失敗するテストを書く(red)
|
||
2. パスさせる(green)
|
||
3. リファクタリングする
|
||
|
||
---
|
||
|
||
## フェーズ 3: コードスメルの特定
|
||
|
||
### コードスメルとは?
|
||
コードに潜むより深い問題の症状である。バグそのものではないが、コード改善の余地を示す指標となる。
|
||
|
||
### よくチェックすべきコードスメル
|
||
|
||
完全なカタログは [references/code-smells.md](references/code-smells.md) を参照。
|
||
|
||
#### クイックリファレンス
|
||
|
||
| スメル | 兆候 | 影響 |
|
||
|-------|-------|--------|
|
||
| **Long Method(長すぎる関数)** | メソッドが 30〜50 行を超える | 理解、テスト、保守が困難 |
|
||
| **Duplicated Code(重複したコード)** | 同じロジックが複数箇所に存在 | バグ修正を複数箇所で行う必要がある |
|
||
| **Large Class(巨大なクラス)** | 責務が多すぎるクラス | 単一責任原則に違反 |
|
||
| **Feature Envy(機能の横恋慕)** | 他クラスのデータを多く使用するメソッド | カプセル化が不十分 |
|
||
| **Primitive Obsession(プリミティブ型への執着)** | オブジェクト化すべき所をプリミティブで多用 | ドメイン概念が欠落 |
|
||
| **Long Parameter List(長すぎるパラメータリスト)** | パラメータが 4 個以上 | 正しく呼び出すのが困難 |
|
||
| **Data Clumps(データの群れ)** | 同じデータ項目が常に一緒に現れる | 抽象化が欠落 |
|
||
| **Switch Statements(スイッチ文)** | 複雑な switch / if-else の連鎖 | 拡張が困難 |
|
||
| **Speculative Generality(投機的一般化)** | 「念のため」のコード | 不要な複雑さ |
|
||
| **Dead Code(デッドコード)** | 使われていないコード | 混乱と保守負担 |
|
||
|
||
### 分析ステップ
|
||
|
||
1. **自動分析**(スクリプトが利用可能な場合)
|
||
```bash
|
||
python scripts/detect-smells.py <file>
|
||
```
|
||
|
||
2. **手動レビュー**
|
||
- コードを体系的に読み進める
|
||
- 各スメルを場所と深刻度とともに記録する
|
||
- 影響度別に分類する(Critical / High / Medium / Low)
|
||
|
||
3. **優先順位付け**
|
||
次のようなスメルに注力する。
|
||
- 現在の開発をブロックしているもの
|
||
- バグや混乱を引き起こしているもの
|
||
- 変更頻度が高いコードパスに影響するもの
|
||
|
||
### 出力: スメルレポート
|
||
|
||
ユーザーへの提示内容:
|
||
- 検出されたスメルの一覧と場所
|
||
- 各スメルの深刻度評価
|
||
- 推奨される優先順位
|
||
- **優先順位の承認を依頼する**
|
||
|
||
---
|
||
|
||
## フェーズ 4: リファクタリング計画の作成
|
||
|
||
### リファクタリング技法の選定
|
||
|
||
各スメルに対して、カタログから適切なリファクタリング技法を選ぶ。
|
||
|
||
完全な一覧は [references/refactoring-catalog.md](references/refactoring-catalog.md) を参照。
|
||
|
||
#### スメル別の推奨リファクタリング
|
||
|
||
| コードスメル | 推奨リファクタリング |
|
||
|------------|---------------------------|
|
||
| Long Method(長すぎる関数) | メソッドの抽出、Replace Temp with Query |
|
||
| Duplicated Code(重複したコード) | メソッドの抽出、Pull Up Method、Form Template Method |
|
||
| Large Class(巨大なクラス) | クラスの抽出、Extract Subclass |
|
||
| Feature Envy(機能の横恋慕) | Move Method、Move Field |
|
||
| Primitive Obsession(プリミティブ型への執着) | Replace Primitive with Object、Replace Type Code with Class |
|
||
| Long Parameter List(長すぎるパラメータリスト) | パラメータオブジェクトの導入、Preserve Whole Object |
|
||
| Data Clumps(データの群れ) | クラスの抽出、パラメータオブジェクトの導入 |
|
||
| Switch Statements(スイッチ文) | ポリモーフィズムによる条件記述の置き換え |
|
||
| Speculative Generality(投機的一般化) | Collapse Hierarchy、Inline Class、デッドコードの削除 |
|
||
| Dead Code(デッドコード) | デッドコードの削除 |
|
||
|
||
### 計画の構成
|
||
|
||
[templates/refactoring-plan.md](templates/refactoring-plan.md) のテンプレートを使用する。
|
||
|
||
各リファクタリングごとに次の項目を埋める。
|
||
1. **対象**: 何を変更するか
|
||
2. **スメル**: どの問題に対処するか
|
||
3. **リファクタリング**: どの技法を適用するか
|
||
4. **手順**: 細かいマイクロステップ
|
||
5. **リスク**: 何が失敗しうるか
|
||
6. **ロールバック**: 取り消す方法
|
||
|
||
### 段階的アプローチ
|
||
|
||
**重要**: リファクタリングはフェーズに分けて段階的に導入する。
|
||
|
||
**フェーズ A: クイックウィン**(低リスク、高価値)
|
||
- 明確化のための変数名変更
|
||
- 明らかな重複コードの抽出
|
||
- デッドコードの削除
|
||
|
||
**フェーズ B: 構造改善**(中リスク)
|
||
- 長すぎる関数からのメソッド抽出
|
||
- パラメータオブジェクトの導入
|
||
- メソッドを適切なクラスへ移動
|
||
|
||
**フェーズ C: アーキテクチャ変更**(高リスク)
|
||
- 条件分岐をポリモーフィズムで置換
|
||
- クラスの抽出
|
||
- デザインパターンの導入
|
||
|
||
### 判断ポイント: ユーザーへの計画提示
|
||
|
||
実装前に:
|
||
- 完全なリファクタリング計画を提示する
|
||
- 各フェーズの内容とリスクを説明する
|
||
- 各フェーズについて明示的な承認を得る
|
||
- **質問**: 「フェーズ A を進めてもよいか?」
|
||
|
||
---
|
||
|
||
## フェーズ 5: 段階的な実装
|
||
|
||
### ゴールデンルール
|
||
> "Change → Test → Green? → Commit → Next step"
|
||
|
||
### 実装のリズム
|
||
|
||
各リファクタリングステップで:
|
||
|
||
1. **事前チェック**
|
||
- テストがパスしている(green)
|
||
- コードがコンパイルできる
|
||
|
||
2. **小さな変更を 1 つだけ行う**
|
||
- カタログのメカニクスに従う
|
||
- 変更は最小限に保つ
|
||
|
||
3. **検証**
|
||
- 直ちにテストを実行
|
||
- コンパイルエラーがないか確認
|
||
|
||
4. **テストがパス(green)した場合**
|
||
- 説明的なコミットメッセージでコミット
|
||
- 次のステップへ進む
|
||
|
||
5. **テストが失敗(red)した場合**
|
||
- 直ちに STOP
|
||
- 変更を取り消す
|
||
- 何が起きたかを分析する
|
||
- 不明な場合はユーザーに確認する
|
||
|
||
### コミット戦略
|
||
|
||
各コミットは次の性質を満たすこと。
|
||
- **アトミック**: 論理的に 1 つの変更
|
||
- **可逆**: 容易に revert できる
|
||
- **説明的**: 明確なコミットメッセージ
|
||
|
||
コミットメッセージ例:
|
||
```
|
||
refactor: Extract calculateTotal() from processOrder()
|
||
refactor: Rename 'x' to 'customerCount' for clarity
|
||
refactor: Remove unused validateOldFormat() method
|
||
```
|
||
|
||
### 進捗報告
|
||
|
||
サブフェーズごとに、ユーザーへ次を報告する。
|
||
- 行った変更
|
||
- テストはまだパスしているか
|
||
- 発生した問題
|
||
- **質問**: 「次のバッチへ進めてもよいか?」
|
||
|
||
---
|
||
|
||
## フェーズ 6: レビューと反復
|
||
|
||
### リファクタリング後チェックリスト
|
||
|
||
- [ ] 全テストがパスする
|
||
- [ ] 新たな警告/エラーが出ていない
|
||
- [ ] コードが正常にコンパイルできる
|
||
- [ ] 振る舞いが変わっていない(手動検証)
|
||
- [ ] 必要に応じてドキュメントが更新されている
|
||
- [ ] コミット履歴が整理されている
|
||
|
||
### メトリクス比較
|
||
|
||
リファクタリング前後で複雑度解析を実施する。
|
||
```bash
|
||
python scripts/analyze-complexity.py <file>
|
||
```
|
||
|
||
改善点を提示する。
|
||
- コード行数の変化
|
||
- 循環的複雑度の変化
|
||
- 保守性指数の変化
|
||
|
||
### ユーザーレビュー
|
||
|
||
最終結果を提示する。
|
||
- 全変更のサマリー
|
||
- Before / After のコード比較
|
||
- メトリクスの改善
|
||
- 残る技術的負債
|
||
- **質問**: 「この変更内容で問題ないか?」
|
||
|
||
### 次のステップ
|
||
|
||
ユーザーと議論する。
|
||
- 追加で対処すべきスメルはあるか?
|
||
- フォローアップのリファクタリングを計画するか?
|
||
- 同様の変更を他箇所にも適用するか?
|
||
|
||
---
|
||
|
||
## 重要なガイドライン
|
||
|
||
### STOP してユーザーに相談すべきタイミング
|
||
|
||
次の場合、必ず一旦止まりユーザーに相談する。
|
||
- ビジネスロジックに不確実性がある
|
||
- 外部 API に影響しうる変更
|
||
- テストカバレッジが不十分
|
||
- 重大なアーキテクチャ判断が必要
|
||
- リスクレベルが上昇する
|
||
- 想定外の複雑さに遭遇した
|
||
|
||
### 安全のためのルール
|
||
|
||
1. **テストなしでリファクタリングしない**(ユーザーが明示的にリスクを受容しない限り)
|
||
2. **大きな変更を一度にしない** - 微小なステップに分割する
|
||
3. **各変更後のテスト実行を省略しない**
|
||
4. **テスト失敗時は続行しない** - 修正かロールバックを先に行う
|
||
5. **思い込みで進めない** - 疑問があれば確認する
|
||
|
||
### やってはいけないこと
|
||
|
||
- リファクタリングと機能追加を同時に行わない
|
||
- 本番障害対応中にリファクタリングしない
|
||
- 理解していないコードをリファクタリングしない
|
||
- 過剰設計をしない - シンプルに保つ
|
||
- 全てを一度にリファクタリングしない
|
||
|
||
---
|
||
|
||
## クイックスタート例
|
||
|
||
### シナリオ: 重複を含む長い関数
|
||
|
||
**Before:**
|
||
```javascript
|
||
function processOrder(order) {
|
||
// 150 行のコードに以下が混在:
|
||
// - 重複したバリデーションロジック
|
||
// - インラインの計算処理
|
||
// - 複数の責務
|
||
}
|
||
```
|
||
|
||
**リファクタリング手順:**
|
||
|
||
1. processOrder() に対する**テストの存在を確認**
|
||
2. バリデーションを validateOrder() に**抽出**
|
||
3. **テスト** - パスすること
|
||
4. 計算を calculateOrderTotal() に**抽出**
|
||
5. **テスト** - パスすること
|
||
6. 通知を notifyCustomer() に**抽出**
|
||
7. **テスト** - パスすること
|
||
8. **レビュー** - processOrder() は明確な 3 関数の調整役となる
|
||
|
||
**After:**
|
||
```javascript
|
||
function processOrder(order) {
|
||
validateOrder(order);
|
||
const total = calculateOrderTotal(order);
|
||
notifyCustomer(order, total);
|
||
return { order, total };
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 参考文献
|
||
|
||
- [Code Smells Catalog](references/code-smells.md) - コードスメルの完全な一覧
|
||
- [Refactoring Catalog](references/refactoring-catalog.md) - リファクタリング技法
|
||
- [Refactoring Plan Template](templates/refactoring-plan.md) - 計画用テンプレート
|
||
|
||
## スクリプト
|
||
|
||
- `scripts/analyze-complexity.py` - コード複雑度メトリクスの分析
|
||
- `scripts/detect-smells.py` - スメルの自動検出
|
||
|
||
## バージョン履歴
|
||
|
||
- v1.0.0 (2025-01-15): Fowler の方法論、段階的アプローチ、ユーザー相談ポイントを備えた初版リリース
|