refactor-flow について
refactor-flow は、リファクタリングと技術的負債を管理し、仕様書とコードの整合性を保つ開発者向けスキルです。コードスメルの分析、計画、安全な変更、文書同期を支援します。
主な機能
- 01コードスメルと複雑度の検出
- 02リファクタリングパターンの提案
- 03コード変更の計画と適用
- 04技術的負債の追跡と優先順位付け
- 05仕様書とトレーサビリティの同期
- 06テスト確認と API 契約の維持
活用シーン
- 01リファクタリング前のモジュール評価
- 02複雑なサービスの段階的変更の計画
- 03コード変更後の仕様書更新
- 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 時間
変更内容:
- 検証ロジックを
_validate_credentials()に抽出します - セッション作成を
_create_session()に抽出します - 監査ログ記録を
_audit_login_attempt()に抽出します - ガード節を使用します
変更前(複雑度: 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 時間
変更内容:
- メール通知用の
EmailServiceを作成します - セキュリティ監査ログ記録用の
AuditLoggerを作成します - セッションキャッシュ用の
SessionCacheを作成します - 依存性注入を更新します
影響分析:
- 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
コメント
Markdown 対応