refactoring-patterns について
動作を変えずにコード構造を改善するためのスキルです。テストを前提に小さく変更し、その都度検証する手順を重視し、代表的なコードスメルとリファクタリング手法を対応づけます。
主な機能
- 01テスト通過をリファクタリングの前提にする
- 02小さく変更して都度テストを実行
- 03コードスメルをリファクタリング手法に対応づける
- 04リファクタリングと機能追加・バグ修正を区別
- 05エージェントによるスメル検出と検証を支援
活用シーン
- 01長いメソッドや責務の多いクラスの分割
- 02重複コードや複雑な条件分岐の整理
- 03リファクタリング前のテスト追加
- 04テストを維持しながら段階的にコードを簡素化
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ proffesor-for-testing/ agentic-qe --skill refactoring-patternsインストール後、Claude Code で/refactoring-patternsを入力して読み込まれたか確認します。
同梱ファイルschemas/output.jsonscripts/validate-config.json
詳細
リファクタリングのパターン
<default_to_action> リファクタリングするときは、次の手順に従います。
- テストが通ることを確認します(テストなしでリファクタリングしないでください)
- 小さな変更を行います(リファクタリングは一度に1つずつ行います)
- テストを実行します(常に成功する状態を保ちます)
- コミットします(進捗を保存します)
- 繰り返します
安全なリファクタリングサイクル:
npm test # Green ✅
# Make ONE small change
npm test # Still green ✅
git commit -m "refactor: extract calculateTotal"
# Repeat
コードの臭い → リファクタリング:
| 臭い | リファクタリング |
|---|---|
| 長すぎるメソッド(20行超) | メソッドの抽出 |
| 大きすぎるクラス | クラスの抽出 |
| 長すぎるパラメーターリスト(3個超) | パラメーターオブジェクトの導入 |
| 重複したコード | メソッド/クラスの抽出 |
| 複雑な条件分岐 | 条件分岐の分解 |
| マジックナンバー | 名前付き定数 |
| 入れ子になったループ | ループをパイプラインに置き換え |
リファクタリングをしてはいけない状況:
- テストがない場合(先にテストを書いてください)
- 締め切りが明日の場合
- 理解していないコード
- 動作していて、今後変更する予定のないコード </default_to_action>
クイックリファレンスカード
よく使うリファクタリング
| パターン | 変更前 | 変更後 |
|---|---|---|
| メソッドの抽出 | 50行の関数 | 5つの小さな関数 |
| クラスの抽出 | 5つの役割を担うクラス | 単一の役割を担う5つのクラス |
| パラメーターオブジェクト | fn(a,b,c,d,e,f) | fn(options) |
| 条件分岐の置き換え | if (type === 'a') {...} | ポリモーフィズム |
| パイプライン | 入れ子になったループ | .filter().map().reduce() |
3回ルール
- 1回目 → そのまま実装します
- 2回目 → ためらいながらも重複させます
- 3回目 → リファクタリングします
主なパターン
メソッドの抽出
// Before: Long method
function processOrder(order) {
// 50 lines of validation, calculation, saving, emailing...
}
// After: Clear responsibilities
function processOrder(order) {
validateOrder(order);
const pricing = calculatePricing(order);
const saved = saveOrder(order, pricing);
sendConfirmationEmail(saved);
return saved;
}
ループをパイプラインに置き換え
// Before
let results = [];
for (let item of items) {
if (item.inStock) {
results.push(item.name.toUpperCase());
}
}
// After
const results = items
.filter(item => item.inStock)
.map(item => item.name.toUpperCase());
条件分岐の分解
// Before
if (order.total > 1000 && customer.isPremium && allInStock(order)) {
return 'FREE_SHIPPING';
}
// After
function isEligibleForFreeShipping(order, customer) {
return isLargeOrder(order) &&
isPremiumCustomer(customer) &&
allInStock(order);
}
リファクタリングのアンチパターン
| ❌ アンチパターン | 問題 | ✅ より良い方法 |
|---|---|---|
| テストなし | 安全網がない | 先にテストを書く |
| 一括変更 | すべてを書き直す | 小さく段階的に進める |
| 完璧を目指す | 終わりのない調整 | 十分な状態で次に進む |
| 早すぎる抽象化 | まだパターンが明確でない | 3回目までは待つ |
| 機能開発中に行う | 変更が混在する | コミットを分ける |
エージェントとの連携
// Detect code smells
const smells = await Task("Detect Code Smells", {
source: 'src/services/',
patterns: ['long-method', 'large-class', 'duplicate-code']
}, "qe-quality-analyzer");
// Safe refactoring with test verification
await Task("Verify Refactoring", {
beforeCommit: 'abc123',
afterCommit: 'def456',
expectSameBehavior: true
}, "qe-test-executor");
エージェント連携のヒント
メモリー名前空間
aqe/refactoring/
├── smells/* - Detected code smells
├── suggestions/* - Refactoring recommendations
├── verifications/* - Behavior preservation checks
└── history/* - Refactoring log
フリートの連携
const refactoringFleet = await FleetManager.coordinate({
strategy: 'refactoring',
agents: [
'qe-quality-analyzer', // Identify targets
'qe-test-generator', // Add safety tests
'qe-test-executor', // Verify behavior
'qe-test-refactorer' // TDD refactor phase
],
topology: 'sequential'
});
関連スキル
- tdd-london-chicago - TDDのリファクタリングフェーズ
- code-review-quality - リファクタリングしたコードをレビューする
- xp-practices - 集合的所有権
覚えておくこと
リファクタリングではないもの:
- 機能の追加
- バグの修正
- パフォーマンスの最適化
- 最初から書き直すこと
リファクタリングとは:
- 構造を改善すること
- コードを読みやすくすること
- 複雑さを減らすこと
- 重複を取り除くこと
- 動作を変えないこと
必ずテストを用意し、必ず小さな手順で進め、必ずテストが成功する状態を保ってください。
コメント
Markdown 対応