# Refactor Master

> This skill should be used when "refactor this", "clean up this code", "improve code structure", "reduce duplication", "extract function", "split this file", "this code is messy", "DRY this up", "improve maintainability".

- Skill: `kwokyc/refactor-master` (Agent Skill)
- Install (CLI): `npx skillmds@latest add kwokyc/refactor-master`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kwokyc/refactor-master/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: KwokYC (https://skillmd.com/u/kwokyc)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/kwokyc/refactor-master

---


# Refactor Master

Systematic refactoring. Make code easier to read, change, and test. Preserve behavior.

## Golden Rule

**Every refactoring must pass all existing tests without modification.** If you need to change tests, it's not refactoring — it's a feature change.

## Before Refactoring Checklist

```
- [ ] Tests exist and pass (if not, write tests FIRST)
- [ ] You understand what the code does
- [ ] You know WHY it needs refactoring (not just "it looks messy")
- [ ] You have a specific goal (readability, testability, performance)
```

## Refactoring Catalog

### 1. Extract Function

When a code block does one identifiable thing but is buried inline.

```python
# ❌ Before
def process_order(order):
    # validate
    if not order.items:
        raise ValueError("Empty order")
    if not order.customer.email:
        raise ValueError("No email")
    if order.total < 0:
        raise ValueError("Negative total")
    # calculate
    subtotal = sum(item.price * item.qty for item in order.items)
    tax = subtotal * 0.08
    total = subtotal + tax
    # ... more code

# ✅ After
def process_order(order):
    validate_order(order)
    total = calculate_order_total(order)
    # ... more code

def validate_order(order):
    if not order.items:
        raise ValueError("Empty order")
    if not order.customer.email:
        raise ValueError("No email")
    if order.total < 0:
        raise ValueError("Negative total")

def calculate_order_total(order):
    subtotal = sum(item.price * item.qty for item in order.items)
    tax = subtotal * 0.08
    return subtotal + tax
```

### 2. Extract Variable

When a complex expression is hard to understand.

```javascript
// ❌ Before
if (order.items.length > 0 && order.customer.isVerified && order.total > 0 && !order.isCancelled) {
  processPayment(order);
}

// ✅ After
const hasItems = order.items.length > 0;
const customerVerified = order.customer.isVerified;
const validTotal = order.total > 0;
const notCancelled = !order.isCancelled;
const isReadyForPayment = hasItems && customerVerified && validTotal && notCancelled;

if (isReadyForPayment) {
  processPayment(order);
}
```

### 3. Inline Function

When a function's body is clearer than its name.

```python
# ❌ Before (function adds indirection without value)
def get_rating(driver):
    return more_than_five_rides(driver) and has_good_reviews(driver)

def more_than_five_rides(driver):
    return driver.total_rides > 5

def has_good_reviews(driver):
    return driver.avg_rating >= 4.5

# ✅ After (inline trivial helpers)
def get_rating(driver):
    return driver.total_rides > 5 and driver.avg_rating >= 4.5
```

### 4. Replace Magic Values

```python
# ❌ Before
if user.role == 3:
    allow_access()
if timeout > 86400:
    refresh_session()

# ✅ After
ROLE_ADMIN = 3
SESSION_TIMEOUT_SECONDS = 86400

if user.role == ROLE_ADMIN:
    allow_access()
if timeout > SESSION_TIMEOUT_SECONDS:
    refresh_session()
```

### 5. Flatten Nested Conditionals

```python
# ❌ Before
def process_payment(order):
    if order:
        if order.items:
            if order.customer:
                if order.customer.verified:
                    return charge(order)
                else:
                    raise Error("Unverified")
            else:
                raise Error("No customer")
        else:
            raise Error("No items")
    else:
        raise Error("No order")

# ✅ After (guard clauses)
def process_payment(order):
    if not order:
        raise Error("No order")
    if not order.items:
        raise Error("No items")
    if not order.customer:
        raise Error("No customer")
    if not order.customer.verified:
        raise Error("Unverified")
    return charge(order)
```

### 6. Remove Duplication (DRY)

```python
# ❌ Before
def send_welcome_email(user):
    server = smtplib.SMTP("smtp.example.com", 587)
    server.starttls()
    server.login("bot@example.com", os.environ["EMAIL_PASS"])
    msg = create_welcome_message(user)
    server.send_message(msg)
    server.quit()

def send_password_reset_email(user):
    server = smtplib.SMTP("smtp.example.com", 587)
    server.starttls()
    server.login("bot@example.com", os.environ["EMAIL_PASS"])
    msg = create_reset_message(user)
    server.send_message(msg)
    server.quit()

# ✅ After
def send_email(user, message_factory):
    with smtplib.SMTP("smtp.example.com", 587) as server:
        server.starttls()
        server.login("bot@example.com", os.environ["EMAIL_PASS"])
        msg = message_factory(user)
        server.send_message(msg)

def send_welcome_email(user):
    send_email(user, create_welcome_message)

def send_password_reset_email(user):
    send_email(user, create_reset_message)
```

### 7. Split Large File

When a file exceeds 300 lines or has multiple responsibilities.

```
❌ user_handler.py (800 lines)
   - Authentication
   - Profile management
   - Avatar upload
   - Notification preferences
   - Account deletion

✅ Split into:
   auth_handler.py
   profile_handler.py
   avatar_handler.py
   notifications_handler.py
   account_handler.py
```

### 8. Replace Temp with Query

```python
# ❌ Before
def get_price(item):
    base_price = item.quantity * item.price
    discount_factor = 0.95 if base_price > 1000 else 0.98
    return base_price * discount_factor

# ✅ After (when base_price and discount_factor are used in multiple places)
def get_price(item):
    return base_price(item) * discount_factor(item)

def base_price(item):
    return item.quantity * item.price

def discount_factor(item):
    return 0.95 if base_price(item) > 1000 else 0.98
```

## Refactoring Decision Tree

```
Is the code hard to read?
  → Extract functions, rename variables, flatten nesting

Is there duplication?
  → Extract shared logic into functions/classes

Is a function too long (>30 lines)?
  → Split into smaller functions by responsibility

Is a file too long (>300 lines)?
  → Split by feature/responsibility

Are there magic numbers/strings?
  → Replace with named constants

Is it hard to test?
  → Extract dependencies, use injection

Is there deep nesting (>3 levels)?
  → Use guard clauses, early returns, extract inner blocks
```

## When NOT to Refactor

```
❌ Don't refactor when:
- No tests exist (write tests first)
- You're in the middle of a feature (finish first)
- The code will be deleted soon
- The "improvement" is just style preference
- Deadline is today (refactor in next sprint)
- You don't understand what the code does
```

## Refactoring Workflow

```
1. Ensure tests pass (run test suite)
2. Make one small change
3. Run tests again
4. Commit if tests pass
5. Repeat from step 2

Never make multiple changes at once.
```

