mcpField
R
refactor-flow

refactor-flow

github.com/vladm3105開発1758 回インストール1 日前に更新
リポジトリ

refactor-flow について

refactor-flow は、リファクタリングと技術的負債を管理し、仕様書とコードの整合性を保つ開発者向けスキルです。コードスメルの分析、計画、安全な変更、文書同期を支援します。

主な機能

  1. 01コードスメルと複雑度の検出
  2. 02リファクタリングパターンの提案
  3. 03コード変更の計画と適用
  4. 04技術的負債の追跡と優先順位付け
  5. 05仕様書とトレーサビリティの同期
  6. 06テスト確認と API 契約の維持

活用シーン

  1. 01リファクタリング前のモジュール評価
  2. 02複雑なサービスの段階的変更の計画
  3. 03コード変更後の仕様書更新
  4. 04モジュール間の技術的負債の優先順位付け

インストール

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

$npx skills add https://github.com/vladm3105/aidoc-flow-framework --skill refactor-flow

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

詳細

refactor-flow

説明: コードのリファクタリング支援、技術的負債の管理、ドキュメントの同期

カテゴリ: コード品質と保守

複雑さ: 中〜高(コード変換+トレーサビリティの維持)


目的

仕様へのトレーサビリティを維持しながら、体系的なリファクタリングによってコード品質を向上させます。リファクタリングの機会を特定し、安全な変換をガイドして、コード変更に合わせてドキュメントが同期された状態を保ちます。


機能

1. コードスメルの検出
  • 長いメソッド: 50行を超える関数
  • ゴッドクラス: 責務が多すぎるクラス
  • 重複コード: 類似したコードブロック
  • デッドコード: 使用されていない関数や変数
  • マジックナンバー: ハードコードされた定数
  • 複雑な条件分岐: ネストされた if 文
  • フィーチャーエンヴィ: 他のクラスのデータを多用するメソッド
  • データの塊: 常に一緒に扱われるデータのグループ
2. リファクタリングの提案
  • メソッドの抽出: 長い関数を分割します
  • クラスの抽出: ゴッドクラスを分割します
  • 名前の変更: 名前をより明確にします
  • 重複の削除: DRY 原則
  • 条件分岐の簡素化: ガード節、ストラテジーパターン
  • パラメーターオブジェクトの導入: パラメーターリストを置き換えます
  • マジックナンバーの置換: 名前付き定数
  • メソッドのインライン化: 不要な間接参照を取り除きます
3. 複雑さの軽減
  • 循環的複雑度を下げます
  • ネストされた構造を簡素化します
  • 依存関係の循環を解消します
  • 凝集度を高めます
  • 結合度を下げます
4. デザインパターンの適用
  • パターンを適用できる箇所を特定します
  • 適切なパターンを提案します
  • パターンの実装をガイドします
  • パターンの使用を検証します
5. 技術的負債の追跡
  • 技術的負債を特定します
  • 負債の深刻度を定量化します
  • 負債削減の優先順位を決めます
  • 負債の傾向を追跡します
6. ドキュメントの同期
  • リファクタリング後に docstring を更新します
  • SPEC ドキュメントをコード変更と同期します
  • トレーサビリティの参照を更新します
  • ADR への準拠を維持します
7. 安全なリファクタリング
  • リファクタリング前にテストがあることを確認します
  • リファクタリング後にテストが成功することを確認します
  • 公開 API の契約を維持します
  • 後方互換性を維持します
8. 自動リファクタリング
  • 単純なリファクタリングを自動修正します
  • リファクタリングの差分を生成します
  • 変換を安全に適用します
  • ロールバック機能

リファクタリングのワークフロー

graph TD
    A[Code Analysis] --> B[Detect Code Smells]
    B --> C{Smells Found?}
    C -->|No| D[Code Quality Good]
    C -->|Yes| E[Prioritize Issues]

    E --> F[Check Test Coverage]
    F --> G{Tests Adequate?}
    G -->|No| H[Write Tests First]
    G -->|Yes| I[Plan Refactoring]

    H --> I
    I --> J[Generate Refactoring Steps]
    J --> K[Execute Refactoring]

    K --> L[Run Tests]
    L --> M{Tests Pass?}
    M -->|No| N[Rollback Changes]
    M -->|Yes| O[Update Documentation]

    N --> P[Revise Approach]
    P --> I

    O --> Q[Validate Traceability]
    Q --> R[Check ADR Compliance]
    R --> S[Generate Refactoring Report]

    S --> T[Commit Changes]

使用方法

リファクタリング対象のコードを分析する
refactor-flow analyze --file src/auth/service.py

出力:

=== Refactoring Analysis: src/auth/service.py ===

Code Smells Found: 6

[HIGH] Long Method (Lines 45-156)
- Method: authenticate_user()
- Length: 112 lines
- Complexity: 15
- Recommendation: Extract validation logic to separate methods
- Estimated effort: 2 hours
- Risk: Low (good test coverage: 95%)

[HIGH] Duplicate Code (85% similarity)
- Locations:
  * Lines 201-215 (validate_password_strength)
  * Lines 234-248 (validate_new_password)
- Recommendation: Extract common logic to shared validator
- Estimated effort: 1 hour
- Risk: Low

[MEDIUM] God Class
- Class: UserAuthenticationService
- Responsibilities: 7 (authentication, validation, logging, caching, email, audit, session)
- Recommendation: Extract email, audit, and caching to separate services
- Estimated effort: 4 hours
- Risk: Medium (affects multiple consumers)

[MEDIUM] Complex Conditional (Lines 89-103)
- Nested depth: 4
- Recommendation: Use guard clauses and early returns
- Estimated effort: 30 minutes
- Risk: Low

[LOW] Magic Numbers (Lines 167, 189, 203)
- Values: 3, 5, 10
- Recommendation: Extract to named constants
- Estimated effort: 15 minutes
- Risk: Very low

[LOW] Dead Code (Lines 278-295)
- Method: legacy_authentication()
- Last used: Never (added 6 months ago)
- Recommendation: Remove if truly unused
- Estimated effort: 5 minutes
- Risk: Very low

Technical Debt Score: 42/100 (High debt)
Refactoring Priority: High
Estimated Total Effort: 7.75 hours
リファクタリング計画を生成する
refactor-flow plan \
  --file src/auth/service.py \
  --priority high \
  --output refactoring-plan.md

生成された計画:

# Refactoring Plan: UserAuthenticationService

## Objective
Reduce complexity and improve maintainability of authentication service

## Current State
- Complexity: 15 (High)
- Lines of code: 356
- Test coverage: 95%
- Technical debt: 42/100

## Target State
- Complexity: <10 (Acceptable)
- Lines of code: <250
- Test coverage: ≥95%
- Technical debt: <20/100

## Refactoring Steps

### Step 1: Extract Password Validation (Priority: High, Risk: Low)
**Duration**: 1 hour

**Changes**:
1. Create `PasswordValidator` class
2. Move `validate_password_strength()` logic
3. Remove duplicate validation code
4. Update tests

**Before**:
```python
def validate_password_strength(self, password):
    if len(password) < 8:
        return False
    if not any(c.isupper() for c in password):
        return False
    # ... more validation

変更後:

class PasswordValidator:
    MIN_LENGTH = 8
    MAX_LENGTH = 128

    @classmethod
    def validate(cls, password: str) -> ValidationResult:
        if len(password) < cls.MIN_LENGTH:
            return ValidationResult(valid=False, error="Too short")
        # ... validation logic

検証:

  • テストが成功する
  • カバレッジが維持されている
  • 重複コードがない

ステップ 2: authenticate_user() を簡素化する(優先度: 高、リスク: 低)

所要時間: 2 時間

変更内容:

  1. 検証ロジックを _validate_credentials() に抽出します
  2. セッション作成を _create_session() に抽出します
  3. 監査ログ記録を _audit_login_attempt() に抽出します
  4. ガード節を使用します

変更前(複雑度: 15):

def authenticate_user(self, username, password):
    if username and password:
        if self._validate_format(username):
            user = self.db.get_user(username)
            if user:
                if user.is_active:
                    if self._check_password(password, user.password_hash):
                        # ... 50 more lines

変更後(複雑度: 5):

def authenticate_user(self, username: str, password: str) -> AuthResult:
    credentials = self._validate_credentials(username, password)
    if not credentials.valid:
        return AuthResult(success=False, error=credentials.error)

    user = self._get_active_user(username)
    if not user:
        return AuthResult(success=False, error="User not found")

    if not self._verify_password(password, user):
        self._audit_login_attempt(username, success=False)
        return AuthResult(success=False, error="Invalid password")

    session = self._create_session(user)
    self._audit_login_attempt(username, success=True)
    return AuthResult(success=True, session=session)

検証:

  • 複雑度が <10 に低下している
  • すべてのテストが成功する
  • 動作に変更がない

ステップ 3: サポートサービスを抽出する(優先度: 中、リスク: 中)

所要時間: 4 時間

変更内容:

  1. メール通知用の EmailService を作成します
  2. セキュリティ監査ログ記録用の AuditLogger を作成します
  3. セッションキャッシュ用の SessionCache を作成します
  4. 依存性注入を更新します

影響分析:

  • UserAuthenticationService の利用箇所は 5 つです
  • すべての利用箇所でインポートの更新が必要です
  • 破壊的変更(MAJOR バージョンの更新)
  • 移行ガイドが必要です

移行ガイド:

# Before
auth_service = UserAuthenticationService()
auth_service.send_verification_email(user)

# After
auth_service = UserAuthenticationService()
email_service = EmailService()
email_service.send_verification(user)

検証:

  • すべての利用箇所が更新されている
  • 結合テストが成功する
  • ドキュメントが更新されている

### Execute Refactoring

```bash
refactor-flow execute \
  --plan refactoring-plan.md \
  --step 1 \
  --dry-run

ドライランの出力:

=== Refactoring Execution (DRY RUN) ===

Step 1: Extract Password Validation

Changes to be made:

1. Create new file: src/auth/validators.py
   [+] 45 lines

2. Modify file: src/auth/service.py
   [-] 30 lines (removed duplicate code)
   [~] 12 lines (updated to use PasswordValidator)

3. Create test file: tests/auth/test_validators.py
   [+] 67 lines

Diff preview:
────────────────────────────────────────
--- src/auth/service.py
+++ src/auth/service.py
@@ -1,5 +1,6 @@
 from datetime import datetime
 from typing import Optional
+from auth.validators import PasswordValidator

 class UserAuthenticationService:
-    def validate_password_strength(self, password: str) -> bool:
-        if len(password) < 8:
-            return False
-        # ... (removed 28 lines)
+    def validate_password_strength(self, password: str) -> bool:
+        result = PasswordValidator.validate(password)
+        return result.valid
────────────────────────────────────────

Test impact:
- Tests to update: 3
- New tests: 8
- Total test count: 156 → 161

Ready to execute? (--dry-run flag active, no changes made)
技術的負債を追跡する
refactor-flow debt \
  --module src/ \
  --output reports/technical-debt.json

出力:

{
  "summary": {
    "total_debt_score": 35,
    "critical_debt_items": 3,
    "high_debt_items": 12,
    "medium_debt_items": 28,
    "estimated_hours": 87
  },
  "debt_by_category": {
    "complexity": {
      "score": 45,
      "items": 8,
      "estimated_hours": 24
    },
    "duplication": {
      "score": 30,
      "items": 15,
      "estimated_hours": 18
    },
    "test_coverage": {
      "score": 20,
      "items": 12,
      "estimated_hours": 30
    },
    "documentation": {
      "score": 25,
      "items": 9,
      "estimated_hours": 15
    }
  },
  "critical_items": [
    {
      "file": "src/data/processor.py",
      "issue": "God class with 12 responsibilities",
      "debt_score": 85,
      "estimated_hours": 16,
      "recommendation": "Split into domain-specific services"
    },
    {
      "file": "src/api/handlers.py",
      "issue": "850 lines, complexity 45",
      "debt_score": 92,
      "estimated_hours": 20,
      "recommendation": "Extract handlers to separate modules"
    }
  ],
  "trend": {
    "previous_score": 40,
    "current_score": 35,
    "change": -5,
    "direction": "improving"
  }
}

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

メソッドの抽出

変更前:

def process_order(order):
    # Validate order (15 lines)
    if not order.items:
        raise ValueError("No items")
    for item in order.items:
        if item.quantity <= 0:
            raise ValueError("Invalid quantity")
    # ... more validation

    # Calculate total (10 lines)
    subtotal = sum(item.price * item.quantity for item in order.items)
    tax = subtotal * 0.08
    shipping = calculate_shipping(order)
    total = subtotal + tax + shipping

    # Process payment (20 lines)
    # ... payment logic

    return total

変更後:

def process_order(order: Order) -> Decimal:
    self._validate_order(order)
    total = self._calculate_total(order)
    self._process_payment(order, total)
    return total

def _validate_order(self, order: Order) -> None:
    if not order.items:
        raise ValueError("No items")
    for item in order.items:
        if item.quantity <= 0:
            raise ValueError(f"Invalid quantity for {item.name}")

def _calculate_total(self, order: Order) -> Decimal:
    subtotal = sum(item.price * item.quantity for item in order.items)
    tax = subtotal * Decimal('0.08')
    shipping = self._calculate_shipping(order)
    return subtotal + tax + shipping
条件分岐をポリモーフィズムに置き換える

変更前:

def calculate_discount(customer, amount):
    if customer.type == 'regular':
        return amount * 0.05
    elif customer.type == 'premium':
        return amount * 0.10
    elif customer.type == 'vip':
        return amount * 0.20
    else:
        return 0

変更後:

class Customer(ABC):
    @abstractmethod
    def calculate_discount(self, amount: Decimal) -> Decimal:
        pass

class RegularCustomer(Customer):
    def calculate_discount(self, amount: Decimal) -> Decimal:
        return amount * Decimal('0.05')

class PremiumCustomer(Customer):
    def calculate_discount(self, amount: Decimal) -> Decimal:
        return amount * Decimal('0.10')

class VIPCustomer(Customer):
    def calculate_discount(self, amount: Decimal) -> Decimal:
        return amount * Decimal('0.20')
パラメーターオブジェクトの導入

変更前:

def create_user(username, email, first_name, last_name, birth_date,
                address, city, state, zip_code, phone, preferences):
    # ... implementation

変更後:

@dataclass
class UserProfile:
    username: str
    email: str
    first_name: str
    last_name: str
    birth_date: date
    contact_info: ContactInfo
    preferences: UserPreferences

def create_user(profile: UserProfile) -> User:
    # ... implementation

リファクタリングのチェックリスト

リファクタリング前
  • コードの動作を理解する
  • テストカバレッジを確認する(80%以上を推奨)
  • SPEC/ADR への準拠を確認する
  • 影響を受ける利用者を特定する
  • バックアップブランチを作成する
  • テストスイート全体を実行する(ベースライン)
リファクタリング中
  • 小さく段階的に変更する
  • 変更のたびにテストを実行する
  • 明確なメッセージを添えてこまめにコミットする
  • 公開 API の契約を維持する
  • 後方互換性を維持する(必要な場合)
  • インラインドキュメントを更新する
リファクタリング後
  • テストスイート全体を実行する
  • カバレッジが維持または向上していることを確認する
  • API を変更した場合は SPEC ドキュメントを更新する
  • トレーサビリティ参照を更新する
  • ADR への準拠を確認する
  • 変更履歴を更新する
  • コードレビューを行う
  • パフォーマンステストを行う(該当する場合)

ドキュメントの同期

メソッドの抽出後
# Before refactoring
def authenticate_user(username, password):
    """
    Authenticate user with username and password.
    Validates credentials, checks user status, creates session.

    Traceability: REQ-AUTH-01, BDD-LOGIN-001
    """

# After refactoring - Update all affected docstrings
def authenticate_user(username: str, password: str) -> AuthResult:
    """
    Authenticate user with username and password.

    Args:
        username: User's login name
        password: User's password

    Returns:
        AuthResult containing success status and session

    Traceability: REQ-AUTH-01, BDD-LOGIN-001
    """

def _validate_credentials(self, username: str, password: str) -> ValidationResult:
    """
    Validate username and password format.

    Traceability: REQ-AUTH-01
    """
SPEC ドキュメントの更新
# SPEC-AUTH-V1.md

## Authentication Service API

### Method: authenticate_user()
**Status**: Updated in v1.2.0 (refactored for clarity)

**Signature**:
```python
def authenticate_user(username: str, password: str) -> AuthResult

v1.2.0 の変更点:

  • 保守性を高めるため、内部実装をリファクタリングしました
  • API の変更はありません(後方互換性があります)
  • エラーメッセージを改善しました
  • 型ヒントを追加しました

トレーサビリティ:REQ-AUTH-01


---

## Risk Assessment

### Low Risk Refactorings
- Rename variables/methods (with IDE support)
- Extract constants
- Inline temporary variables
- Remove dead code
- Add type hints
- Improve docstrings

### Medium Risk Refactorings
- Extract method
- Extract class
- Move method
- Replace conditional with polymorphism
- Introduce parameter object

### High Risk Refactorings
- Change class hierarchy
- Split database tables
- Modify public API
- Change authentication mechanism
- Refactor core business logic

### Risk Mitigation
1. **Excellent test coverage**: ≥95% for high-risk refactorings
2. **Feature flags**: Enable gradual rollout
3. **Parallel run**: Run old and new code, compare results
4. **Staged rollout**: Canary deployment
5. **Rollback plan**: Quick revert capability
6. **Monitoring**: Extra logging during transition

---

## Tool Access

Required tools:
- `Read`: Read source files and documentation
- `Edit`: Apply refactoring transformations
- `Write`: Create new files
- `Bash`: Run tests and analysis tools
- `Grep`: Search for code patterns

Required libraries:
- rope: Python refactoring library
- autopep8: Code formatting
- radon: Complexity metrics
- pylint: Code analysis

---

## Integration Points

### With code-review
- Identify refactoring opportunities from reviews
- Validate refactoring quality
- Track complexity improvements

### With test-automation
- Ensure tests exist before refactoring
- Run tests after each refactoring step
- Verify coverage maintained

### With doc-validator
- Sync documentation with code changes
- Validate traceability after refactoring
- Update cross-references

### With analytics-flow
- Track technical debt trends
- Measure refactoring impact
- Report debt reduction progress

---

## Best Practices

1. **Test first**: Ensure good test coverage before refactoring
2. **Small steps**: Incremental changes, frequent commits
3. **One thing at a time**: Don't mix refactoring with new features
4. **Preserve behavior**: No functional changes during refactoring
5. **Run tests constantly**: After every small change
6. **Review changes**: Code review for refactorings
7. **Update documentation**: Keep specs synchronized
8. **Monitor performance**: Ensure no performance regressions
9. **Communicate**: Notify team of significant refactorings
10. **Schedule wisely**: Not during critical deadlines

---

## Success Criteria

- Code complexity reduced to target levels
- Test coverage maintained or improved
- Zero functional regressions
- Documentation synchronized
- Traceability preserved
- Team understands changes
- Technical debt score improved by ≥20%

---

## Notes

- Refactoring plans saved to `plans/refactoring/`
- Refactoring reports in `reports/refactoring/`
- Technical debt tracked in `metrics/technical-debt.json`
- Automated refactorings require manual review
- High-risk refactorings need team approval

コメント