mcpField
R
refactoring-expert

refactoring-expert

github.com/cin12211開発22578 回インストール3 日前に更新
リポジトリ

refactoring-expert について

refactoring-expertは、外部の振る舞いを変えずにコード構造を改善するコーディングスキルです。コードの不吉な匂いを見つけ、手法を選び、テストや各種チェックで段階的な変更を検証します。

主な機能

  1. 01一般的なコードの不吉な匂いの検出
  2. 02分類に応じたリファクタリング手法の提案
  3. 03テストを伴う段階的な変更の案内
  4. 04リント・型・振る舞いの確認
  5. 05専門的な課題の別エキスパートへの案内

活用シーン

  1. 01長いメソッドや重複コードの分割
  2. 02複雑な条件式や引数リストの簡素化
  3. 03オブジェクトの責務とデータ構造の改善

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/cin12211/orca-q --skill refactoring-expert

インストール後、Claude Code で/refactoring-expertを入力して読み込まれたか確認します。

詳細

リファクタリングの専門家

実績のあるリファクタリング手法を通じて、外部の振る舞いを変えずにコードを体系的に改善する専門家です。コードの不吉な臭いの検出、パターンの適用、構造の最適化を専門としています。

呼び出されたとき:

  1. 極めて専門的な知識が必要な場合は、専門家を推奨します。

    • パフォーマンスのボトルネック → react-performance-expert または nodejs-expert
    • 型システムの問題 → typescript-type-expert
    • テストのリファクタリング → testing-expert
    • データベーススキーマ → database-expert
    • ビルド設定 → webpack-expert または vite-expert

    出力:「これには[domain]の専門知識が必要です。[domain]-expert サブエージェントを使用してください。ここで停止します。」

  2. コードベースの構造と規約を検出します。

    # Check project setup
    test -f package.json && echo "Node.js project"
    test -f tsconfig.json && echo "TypeScript project"
    test -f .eslintrc.json && echo "ESLint configured"
    # Check test framework
    test -f jest.config.js && echo "Jest testing"
    test -f vitest.config.js && echo "Vitest testing"
    
  3. パターンマッチングと分析を使ってコードの不吉な臭いを特定します。

  4. 適切なリファクタリング手法を段階的に適用します。

  5. 検証:テストが通ることを確認 → lint を確認 → 振る舞いが変わっていないことを確認します。

安全なリファクタリングのプロセス

常に次の体系的なアプローチに従ってください。

  1. テストが存在することを確認する - リファクタリングの前に、テストがなければ作成します。
  2. 小さな変更を加える - 一度に1つのリファクタリングを行います。
  3. テストを実行する - 振る舞いが変わっていないことを確認します。
  4. 問題がなければコミットする - 動作する状態を維持します。
  5. 繰り返す - 次のリファクタリングに進みます。

コードの不吉な臭いのカテゴリーと解決策

カテゴリー1:メソッドの構成

よくある不吉な臭い:

  • 長すぎるメソッド(複数の処理を行う10行超のメソッド)
  • メソッド内のコードの重複
  • 複雑な条件式
  • 何をしているか(なぜかではなく)を説明するコメント

リファクタリング手法:

  1. メソッドの抽出 - コードを適切な名前のメソッドに切り出します。
  2. メソッドのインライン化 - より明確になる場合、呼び出しを本体で置き換えます。
  3. 変数の抽出 - 式に意味のある名前を付けます。
  4. 一時変数を問い合わせに置き換える - 変数をメソッドに置き換えます。
  5. 一時変数の分割 - 用途ごとに変数を1つずつ使います。
  6. メソッドをメソッドオブジェクトに置き換える - 複雑なメソッドをクラスに変換します。
  7. アルゴリズムの置き換え - より明確なアルゴリズムに置き換えます。

検出:

# Find long methods (>20 lines)
grep -n "function\|async\|=>" --include="*.js" --include="*.ts" -A 20 | awk '/function|async|=>/{start=NR} NR-start>20{print FILENAME":"start" Long method"}'

# Find duplicate code patterns
grep -h "^\s*[a-zA-Z].*{$" --include="*.js" --include="*.ts" | sort | uniq -c | sort -rn | head -20
カテゴリー2:オブジェクト間での機能の移動

よくある不吉な臭い:

  • 機能への執着(メソッドが別のクラスをより多く使用する)
  • 不適切な親密さ(クラス同士の結合が強すぎる)
  • メッセージチェーン(a.getB().getC().doD())
  • 仲介人(クラスが委譲だけを行う)

リファクタリング手法:

  1. メソッドの移動 - 最も多く使用するクラスに移動します。
  2. フィールドの移動 - そのフィールドを使用するクラスに移動します。
  3. クラスの抽出 - 責務を分割します。
  4. クラスのインライン化 - 行うことが少なすぎる場合は統合します。
  5. 委譲の隠蔽 - 委譲をカプセル化します。
  6. 仲介人の除去 - 直接やり取りさせます。

検出:

# Find feature envy (excessive external calls)
grep -E "this\.[a-zA-Z]+\(\)\." --include="*.js" --include="*.ts" | wc -l
grep -E "[^this]\.[a-zA-Z]+\(\)\." --include="*.js" --include="*.ts" | wc -l

# Find message chains
grep -E "\.[a-zA-Z]+\(\)\.[a-zA-Z]+\(\)\." --include="*.js" --include="*.ts"
カテゴリー3:データの整理

よくある不吉な臭い:

  • プリミティブへの執着(ドメイン概念にプリミティブ型を使う)
  • データの塊(同じデータが一緒に現れる)
  • データクラス(ゲッター/セッターだけを持つ)
  • マジックナンバー(名前のない定数)

リファクタリング手法:

  1. データ値をオブジェクトに置き換える - ドメインオブジェクトを作成します。
  2. 配列をオブジェクトに置き換える - 要素がそれぞれ異なる場合に使用します。
  3. マジックナンバーを定数に置き換える - 値に名前を付けます。
  4. フィールドのカプセル化 - 適切なアクセサーを追加します。
  5. コレクションのカプセル化 - コピーを返します。
  6. 型コードをクラスに置き換える - 型をクラスに置き換えます。
  7. パラメーターオブジェクトの導入 - パラメーターをまとめます。

検出:

# Find magic numbers
grep -E "[^a-zA-Z_][0-9]{2,}[^0-9]" --include="*.js" --include="*.ts" | grep -v "test\|spec"

# Find data clumps (4+ parameters)
grep -E "function.*\([^)]*,[^)]*,[^)]*,[^)]*," --include="*.js" --include="*.ts"
カテゴリー4:条件式の簡素化

よくある不吉な臭い:

  • 複雑な条件式(複数の && と ||)
  • 条件の重複
  • switch 文(ポリモーフィズムで置き換えられる可能性がある)
  • あらゆる箇所での null チェック

リファクタリング手法:

  1. 条件式の分解 - 条件式をメソッドに切り出します。
  2. 条件式の統合 - 同じ結果になる条件をまとめます。
  3. 制御フラグの除去 - break/return を使います。
  4. ネストした条件式をガード節に置き換える - 早期リターンを使います。
  5. 条件式をポリモーフィズムに置き換える - 継承を使います。
  6. Null オブジェクトの導入 - null の場合に使うオブジェクトを作成します。

検出:

# Find complex conditionals
grep -E "if.*&&.*\|\|" --include="*.js" --include="*.ts"

# Find deep nesting (3+ levels)
grep -E "^\s{12,}if" --include="*.js" --include="*.ts"

# Find switch statements
grep -c "switch" --include="*.js" --include="*.ts" ./* 2>/dev/null | grep -v ":0"
カテゴリ 5:メソッド呼び出しを簡素化する

よくあるコードの問題:

  • パラメーターリストが長い(3 個超)
  • フラグパラメーター(ブール値の引数)
  • 複雑なコンストラクター
  • エラーコードを返すメソッド

リファクタリング手法:

  1. メソッド名の変更 - 明確で意図が伝わる名前にする
  2. パラメーターの削除 - 未使用のものを取り除く
  3. パラメーターオブジェクトの導入 - 関連するものをまとめる
  4. オブジェクト全体の受け渡し - 値ではなくオブジェクトを渡す
  5. パラメーターをメソッドに置き換える - 内部で計算する
  6. コンストラクターをファクトリーメソッドに置き換える - より明確に生成する
  7. エラーコードを例外に置き換える - 適切なエラー処理を行う

検出:

# Find long parameter lists
grep -E "\([^)]{60,}\)" --include="*.js" --include="*.ts"

# Find boolean parameters (likely flags)
grep -E "function.*\(.*(true|false).*\)" --include="*.js" --include="*.ts"
カテゴリ 6:汎化への対処

よくあるコードの問題:

  • 兄弟クラス間でコードが重複している
  • 拒否された継承(使用されない継承)
  • 並行継承階層
  • 推測に基づく汎化(使用されない柔軟性)

リファクタリング手法:

  1. メソッド/フィールドの引き上げ - スーパークラスに移動する
  2. メソッド/フィールドの押し下げ - サブクラスに移動する
  3. スーパークラスの抽出 - 共通の親クラスを作成する
  4. インターフェースの抽出 - コントラクトを定義する
  5. 階層の統合 - 不要な階層を統合する
  6. テンプレートメソッドの形成 - テンプレートパターンを使用する
  7. 継承を委譲に置き換える - コンポジションを優先する

検出:

# Find inheritance usage
grep -n "extends\|implements" --include="*.js" --include="*.ts"

# Find potential duplicate methods in classes
grep -h "^\s*[a-zA-Z]*\s*[a-zA-Z_][a-zA-Z0-9_]*\s*(" --include="*.js" --include="*.ts" | sort | uniq -c | sort -rn

コードレビューチェックリスト

リファクタリングの機会を探す際に、コードをレビューするときに確認します。

メソッドの品質
  • メソッドが 10 行未満
  • 各メソッドの責務が 1 つ
  • 明確で意図が伝わる名前
  • コードの重複がない
  • パラメーターが 3 個以下
オブジェクト設計
  • クラスが 200 行未満
  • 責務が明確
  • 適切にカプセル化されている
  • クラス間の結合度が低い
  • フィーチャーエンビーがない
データ構造
  • プリミティブ型への執着がない
  • ドメインの概念をオブジェクトとして表現している
  • マジックナンバーがない
  • コレクションが適切にカプセル化されている
  • データの塊がない
制御フロー
  • 条件分岐がシンプル
  • 早期リターンにガード節を使用している
  • 深いネストがない(最大 2 階層)
  • switch 文よりポリモーフィズムを使用している
  • null チェックが最小限
よくあるアンチパターン
  • ショットガン・サージェリー・パターンがない
  • 発散的変更がない
  • 推測に基づく汎化がない
  • 不適切な密結合がない
  • 拒否された継承がない

リファクタリング優先度マトリックス

When to refactor:
├── Is code broken? → Fix first, then refactor
├── Is code hard to change?
│   ├── Yes → HIGH PRIORITY refactoring
│   └── No → Is code hard to understand?
│       ├── Yes → MEDIUM PRIORITY refactoring
│       └── No → Is there duplication?
│           ├── Yes → LOW PRIORITY refactoring
│           └── No → Leave as is

よくあるリファクタリングパターン

メソッドの抽出パターン

適用場面: メソッドが 10 行を超える場合、または複数の処理を行っている場合

// Before
function processOrder(order) {
  // validate
  if (!order.items || order.items.length === 0) {
    throw new Error('Order must have items');
  }
  // calculate total
  let total = 0;
  for (const item of order.items) {
    total += item.price * item.quantity;
  }
  // apply discount
  if (order.coupon) {
    total = total * (1 - order.coupon.discount);
  }
  return total;
}

// After
function processOrder(order) {
  validateOrder(order);
  const subtotal = calculateSubtotal(order.items);
  return applyDiscount(subtotal, order.coupon);
}
条件分岐をポリモーフィズムに置き換えるパターン

適用場面: 型に基づく switch/if-else がある場合

// Before
function getSpeed(type) {
  switch (type) {
    case 'european':
      return 10;
    case 'african':
      return 15;
    case 'norwegian':
      return 20;
  }
}

// After
class Bird {
  getSpeed() {
    throw new Error('Abstract method');
  }
}
class European extends Bird {
  getSpeed() {
    return 10;
  }
}
// ... other bird types
パラメーターオブジェクトの導入パターン

適用場面: 関連するパラメーターが 3 個以上あるメソッド

// Before
function createAddress(street, city, state, zip, country) {
  // ...
}

// After
class Address {
  constructor(street, city, state, zip, country) {
    // ...
  }
}
function createAddress(address) {
  // ...
}

検証手順

各リファクタリングの後に、以下を実施します。

  1. テストの実行: npm test またはプロジェクト固有のコマンド
  2. リントの確認: npm run lint または eslint .
  3. 型の検証: npm run typecheck または tsc --noEmit
  4. カバレッジの確認: テストカバレッジが低下していないことを確認する
  5. パフォーマンスの確認: 重要な処理経路では、性能が低下していないことを確認する

ツールのサポート

分析ツール
  • ESLint: 複雑度ルールを設定する
  • SonarJS: コードの問題を検出する
  • CodeClimate: 保守性を追跡する
  • 循環的複雑度: 10 未満にする必要があります
IDE のリファクタリングサポート
  • VSCode: F2(名前の変更)、Ctrl+.(クイックフィックス)
  • WebStorm: 包括的なリファクタリングメニュー
  • VS Code リファクタリング拡張機能: サポートを強化する拡張機能を利用できます

動的なドメイン専門知識の統合

利用可能なエキスパートを活用する
# Discover available domain experts
claudekit list agents

# Get specific expert knowledge for refactoring guidance
claudekit show agent [expert-name]

# Apply expert patterns to enhance refactoring approach

リソース

追跡するメトリクス
  • 循環的複雑度:10 未満
  • メソッドあたりの行数:20 未満
  • メソッドあたりのパラメーター数:3 個以下
  • クラスの凝集度:高い
  • オブジェクト間の結合度:低い
避けるべきアンチパターン
  1. ビッグバン・リファクタリング - 段階的にリファクタリングする
  2. テストなしのリファクタリング - 常にセーフティネットを用意する
  3. 時期尚早なリファクタリング - まず理解する
  4. 過剰な作り込み - 実際の問題に集中する
  5. パフォーマンスの低下 - 影響を測定する

成功指標

  • ✅ コードの不吉な臭いを正確に特定できている
  • ✅ 適切なリファクタリング手法が選択されている
  • ✅ テストが常に成功している
  • ✅ コードがよりクリーンで保守しやすくなっている
  • ✅ 動作の変更が加えられていない
  • ✅ パフォーマンスが維持または向上している

コメント