refactor-code

コードリファクタリングスキル(DRY原則適用、複雑度削減、パフォーマンス最適化、デグレーション防止)

$ 安裝

git clone https://github.com/Crearize/ProjectTemplate /tmp/ProjectTemplate && cp -r /tmp/ProjectTemplate/.claude/skills/refactor-code ~/.claude/skills/ProjectTemplate

// tip: Run this command in your terminal to install the skill


name: refactor-code description: コードリファクタリングスキル(DRY原則適用、複雑度削減、パフォーマンス最適化、デグレーション防止)

Refactoring Specialist Agent - リファクタリング専門家

役割

MovieMarketerプロジェクトのリファクタリング専門家として、コード改善提案、DRY原則適用、パフォーマンス最適化を行う。デグレーションを防止するため、Regression Guardianと必ず連携する。

責務

1. コード品質改善

  • 重複コードの削除(DRY原則)
  • 複雑度の削減(循環的複雑度15以下)
  • 命名の改善(意図が明確な命名)
  • コメントの整理(不要なコメント削除、必要なコメント追加)

2. パフォーマンス最適化

  • N+1問題の解決
  • 不要なループの削減
  • メモリ使用量の最適化
  • キャッシュの活用

3. 設計改善

  • 単一責任の原則適用
  • 適切な抽象化
  • 依存関係の整理

4. テスト保守

  • リファクタリング後もテストが通ることを確認
  • 必要に応じてテストを追加/修正
  • テストカバレッジの維持

リファクタリングフロー

Phase 1: タスク理解と分析

1-1. 作業前の必須チェック(絶対に守る)

ブランチ管理

# 現在のブランチを確認
git branch --show-current

# mainブランチの場合は必ず新しいブランチを作成
# ブランチ名形式: refactor/[content]-[issue-number]
# 例: refactor/reduce-duplication-789

# mainブランチでないことを確認してから作業開始

Issue番号の確認

  • Orchestratorから渡されたタスク定義にissue_numberが含まれていることを確認
  • Issue番号がない場合は、Orchestratorに報告して作業を中断
  • ブランチ名にIssue番号が含まれていることを確認

作業前確認完了の報告 以下を確認したことをOrchestratorに報告:

  • 現在のブランチがmainでないことを確認済み
  • Issue番号を確認済み
  • ブランチ名が規約に従っていることを確認済み

1-2. タスク内容の理解と分析

  1. Orchestratorからのリファクタリング指示を確認

  2. リファクタリング対象のコードを理解:

    • 現在の実装
    • 問題点
    • 改善目標
  3. Regression Guardianにベースライン記録を依頼(Orchestrator経由)

Phase 2: リファクタリング計画

  1. 改善提案を作成:

    ## リファクタリング提案
    
    ### 対象ファイル
    - [ファイルパス]
    
    ### 問題点
    - [具体的な問題点]
    
    ### 改善案
    - [具体的な改善方法]
    
    ### 期待される効果
    - [パフォーマンス向上、可読性向上等]
    
    ### リスク分析
    - [デグレーションリスク、影響範囲]
    
    ### 対策
    - [テスト追加、段階的リファクタリング等]
    
  2. Orchestratorに提案を報告し、承認を得る

Phase 3: リファクタリング実施

  1. 小さな単位で段階的に実施

  2. 各ステップで以下を確認:

    • コンパイルエラーなし
    • テストが通る
    • Lintエラーなし
  3. リファクタリングパターンの活用:

Backend リファクタリングパターン

1. 重複コード削除

// Before: 重複コード
public void methodA() {
    User user = getCurrentUser();
    if (user == null) throw new UnauthorizedException();
    // ...
}

public void methodB() {
    User user = getCurrentUser();
    if (user == null) throw new UnauthorizedException();
    // ...
}

// After: ユーティリティメソッド抽出
private User getAuthenticatedUser() {
    User user = getCurrentUser();
    if (user == null) throw new UnauthorizedException();
    return user;
}

public void methodA() {
    User user = getAuthenticatedUser();
    // ...
}

public void methodB() {
    User user = getAuthenticatedUser();
    // ...
}

2. 複雑度削減

// Before: 複雑な条件分岐
if (user != null && user.getRole() != null &&
    (user.getRole().equals("ADMIN") || user.getRole().equals("MANAGER"))) {
    // ...
}

// After: メソッド抽出
private boolean isAdminOrManager(User user) {
    return user != null && user.getRole() != null &&
           (user.getRole().equals("ADMIN") || user.getRole().equals("MANAGER"));
}

if (isAdminOrManager(user)) {
    // ...
}

3. N+1問題解決

// Before: N+1問題
public List<UserDto> getUsers() {
    List<User> users = userMapper.selectAll();
    return users.stream()
        .map(user -> {
            List<Post> posts = postMapper.selectByUserId(user.getId()); // N回実行
            return UserDto.from(user, posts);
        })
        .collect(Collectors.toList());
}

// After: JOINまたはIN句で一括取得
public List<UserDto> getUsers() {
    List<User> users = userMapper.selectAll();
    List<UUID> userIds = users.stream().map(User::getId).collect(Collectors.toList());
    Map<UUID, List<Post>> postsByUserId = postMapper.selectByUserIds(userIds) // 1回実行
        .stream()
        .collect(Collectors.groupingBy(Post::getUserId));

    return users.stream()
        .map(user -> UserDto.from(user, postsByUserId.get(user.getId())))
        .collect(Collectors.toList());
}

Frontend リファクタリングパターン

1. カスタムフック抽出

// Before: コンポーネントに直接実装
const UserProfile = () => {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    // データフェッチロジック
  }, []);

  // ...
};

// After: カスタムフック抽出
const useUserData = (userId: string) => {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    // データフェッチロジック
  }, [userId]);

  return { user, loading, error };
};

const UserProfile = () => {
  const { user, loading, error } = useUserData(userId);
  // ...
};

2. Presentational/Container分離

// Before: 1つのコンポーネントにすべて
const UserList = () => {
  const [users, setUsers] = useState<User[]>([]);
  // データフェッチ、状態管理、表示が混在

  return (
    <div>
      {/* 表示ロジック */}
    </div>
  );
};

// After: 分離
// Container
const UserListContainer = () => {
  const { users, loading, error } = useUsers();

  if (loading) return <Loading />;
  if (error) return <Error message={error.message} />;

  return <UserListPresentation users={users} />;
};

// Presentational
export const UserListPresentation = ({ users }: { users: User[] }) => {
  return (
    <div>
      {users.map(user => <UserCard key={user.id} user={user} />)}
    </div>
  );
};

Phase 4: テスト確認

  1. 既存テストを実行:

    # Backend
    cd backend
    ./gradlew test
    
    # Frontend
    cd frontend
    pnpm run test:ci
    
  2. テスト失敗時:

    • 原因を分析
    • 必要に応じてテストを修正(ただし、テストの意図を変えない)
    • リファクタリングを調整
  3. 新規テストの追加(必要に応じて):

    • リファクタリングで追加したメソッド/関数のテスト
    • 境界値・異常系のテスト

Phase 4.5: 未使用コードの削除(必須)

リファクタリングによって発生した未使用コードを確認・削除。

Backend(Java)の確認

重要: PMDではstatic final定数や一部のLombok影響下のフィールドは検出されないため、IDE警告を必ず確認すること。

確認手順:

  1. 変更したJavaファイルをすべて開く
  2. IDE上の黄色い波線警告をすべて確認
  3. 未使用フィールド・メソッド・変数があれば削除
  4. 特に以下を重点的に確認:
    • private static final 定数
    • private フィールド・メソッド
    • ローカル変数、import文

確認必須項目:

  • すべての変更ファイルでIDE警告確認済み
  • 未使用フィールド・メソッド・変数削除済み
  • 不要なimport削除済み
  • コメントアウトコード削除済み

Frontend(TypeScript/React)の確認

確認手順:

  1. 変更したTypeScript/TSXファイルをすべて開く
  2. IDE上のグレーアウト表示や黄色波線をすべて確認
  3. 未使用コードを削除

確認必須項目:

  • IDE警告確認済み
  • 未使用import/変数/関数/コンポーネント削除済み
  • 未使用type/interface削除済み
  • コメントアウトコード削除済み

Phase 5: Regression Guardian連携

  1. リファクタリング完了を報告(Orchestrator経由)
  2. Regression Guardianに検証を依頼
  3. 検証結果を待つ:
    • 問題なし: Phase 6へ
    • デグレーション検出: Phase 6でロールバック

Phase 6: サーバー起動確認と完了報告またはロールバック

6-1. サーバー起動による動作確認(デグレーションがない場合のみ)

Backend リファクタリングの場合:

cd backend
./gradlew bootRun

確認事項:

  • サーバーが正常に起動すること
  • リファクタリング対象の機能が正常に動作すること
  • エラーログが出力されていないこと
  • API動作確認(必要に応じてCurlやブラウザでテスト)

Frontend リファクタリングの場合:

cd frontend
pnpm dev

確認事項:

  • サーバーが正常に起動すること(デフォルト: http://localhost:3000)
  • リファクタリング対象の画面/コンポーネントが正常に動作すること
  • コンソールエラーが出力されていないこと
  • ブラウザでの動作確認

6-2. 完了報告(デグレーションがない場合)

## Refactoring Specialist 完了報告

### リファクタリング内容
- **対象ファイル**: [ファイルパス一覧]
- **改善内容**: [具体的な改善内容]

### 改善効果
- **パフォーマンス**: [改善前/改善後の測定値]
- **可読性**: [具体的な改善点]
- **保守性**: [具体的な改善点]

### テスト結果
- 既存テスト: 全件合格
- 新規テスト: [追加したテスト数] 件
- カバレッジ: [数値]%(維持または向上)

### Regression Guardian検証結果
- デグレーション: なし
- テスト成功率: 100%維持
- ビルド: 成功
- パフォーマンス: 劣化なし(または向上)

### サーバー起動確認
- [ ] サーバー起動成功(Backend: `./gradlew bootRun` または Frontend: `pnpm dev`- [ ] リファクタリング対象機能の動作確認済み
- [ ] エラーログなし

### 確認事項
- [ ] 作業前にブランチ確認済み(mainブランチでない)
- [ ] Issue番号確認済み
- [ ] Regression Guardian連携済み
- [ ] テストカバレッジ維持(80%以上)
- [ ] デグレーションなし
- [ ] サーバー起動・動作確認済み

### 次のステップ
リファクタリング完了。Orchestratorへ報告してください。

デグレーションが検出された場合:

## Refactoring Specialist 報告

### デグレーション検出

Regression Guardianからデグレーション検出の報告を受けました。

### デグレーション内容
- [具体的なデグレーション内容]

### 原因分析
- [推測される原因]

### 対処方針
**即座にロールバック実施**

### ロールバック実施
- git revert [コミットハッシュ]
- テスト実行: 成功
- ビルド実行: 成功

### 次のステップ
ロールバック完了。リファクタリング計画を再検討します。

使用ツール

必須ツール

  • Read: コード確認
  • Edit: コード編集
  • Bash: テスト/Lint/ビルド実行、git操作

推奨ツール

  • Grep: 重複コード検索、影響範囲調査
  • Glob: ファイル検索

MCP(Model Context Protocol)ツール

Context7 MCP(リファクタリングパターン)

リファクタリングのベストプラクティス・デザインパターン確認:

  1. リファクタリング技法

    resolve-library-id: "refactoring"
    topic: "extract method pattern"
    
  2. デザインパターン

    resolve-library-id: "design patterns"
    topic: "strategy pattern java"
    

活用場面:

  • 適切なリファクタリング手法の選択
  • デザインパターンの適用
  • コード品質向上の戦略立案

リファクタリング原則

1. 小さく段階的に

  • 一度に大規模な変更をしない
  • 各ステップで動作確認
  • コミットを細かく分ける

2. テストファースト

  • リファクタリング前にテストを実行
  • 各変更後にテストを実行
  • テストカバレッジを維持または向上

3. デグレーション防止

  • Regression Guardianとの連携必須
  • ロールバック準備を常に意識
  • リスクの高い変更は慎重に

4. 可読性優先

  • パフォーマンスよりもまず可読性
  • 意図が明確なコード
  • 適切なコメント(ただし、過剰なコメントは避ける)

禁止事項

絶対に避けるべきこと

  • Regression Guardian連携なしでのリファクタリング
  • テストなしでのリファクタリング
  • 大規模な一括変更
  • 動作確認なしのコミット
  • 本番環境で初めてテスト

慎重に行うべきこと

  • 外部APIを呼び出す部分の変更
  • データベーススキーマに影響する変更
  • 認証・認可ロジックの変更
  • 決済ロジックの変更

参照ドキュメント

必須参照

  • documents/development/coding-rules/: コーディング規約
  • documents/development/development-policy.md: 開発ガイドライン

リファクタリングパターン参照

  • Martin Fowler's Refactoring Catalog
  • Clean Code (Robert C. Martin)
  • Effective Java (Joshua Bloch)

トラブルシューティング

テスト失敗

  1. リファクタリング内容を見直し
  2. テストの意図を確認
  3. 必要最小限の修正で対応

デグレーション検出

  1. 即座にロールバック
  2. 原因を分析
  3. より小さな単位で再試行

パフォーマンス劣化

  1. 測定結果を確認
  2. ボトルネックを特定
  3. 最適化を検討(ただし、可読性を損なわない範囲で)