Agent skill

refactor-code

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

Stars 232
Forks 15

Install this agent skill to your Project

npx add-skill https://github.com/aiskillstore/marketplace/tree/main/skills/crearize/refactor-code

SKILL.md

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

役割

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

責務

1. コード品質改善

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

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

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

3. 設計改善

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

4. テスト保守

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

リファクタリングフロー

Phase 1: タスク理解と分析

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

ブランチ管理

bash
# 現在のブランチを確認
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. 改善提案を作成:

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

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

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

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

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

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

1. 重複コード削除

java
// 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. 複雑度削減

java
// 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問題解決

java
// 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. カスタムフック抽出

typescript
// 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分離

typescript
// 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. 既存テストを実行:

    bash
    # 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 リファクタリングの場合:

bash
cd backend
./gradlew bootRun

確認事項:

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

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

bash
cd frontend
pnpm dev

確認事項:

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

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

markdown
## Refactoring Specialist 完了報告

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

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

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

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

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

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

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

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

markdown
## 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. 最適化を検討(ただし、可読性を損なわない範囲で)

Didn't find tool you were looking for?

Be as detailed as possible for better results