Claude-skill-registry Keeping Routines Focused

Each routine does one thing and does it well - extract when routines have multiple responsibilities

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/keeping-routines-focused" ~/.claude/skills/majiayu000-claude-skill-registry-keeping-routines-focused && rm -rf "$T"
manifest: skills/data/keeping-routines-focused/SKILL.md
source content

Keeping Routines Focused

Overview

A routine should do ONE thing and do it well. This is called functional cohesion - the strongest, best kind of cohesion.

Core principle: If a routine's description contains "and", it's doing too many things. Extract into focused routines.

Goal: Improve intellectual manageability. The more focused a routine, the easier to understand, test, modify, and reuse.

When to Use

Proactively (writing new code):

  • Designing new functions/methods
  • Writing routine specifications
  • Naming routines (if name is vague or has "and", too many responsibilities)

Reactively (improving existing code):

  • Reviewing code with long routines
  • Refactoring when routine does multiple things
  • When routine is hard to understand or test
  • When routine keeps growing with each modification

Warning signs routine needs focus:

  • Description has "and" in it
  • Routine name is vague or long
  • Routine is hard to name clearly
  • Routine is > 200 lines (strong signal)
  • Parameter list > 7 parameters
  • Many local variables (> 10)
  • Multiple levels of abstraction mixed
  • Does validation AND calculation AND side-effects
  • Hard to write test (does too much to test atomically)

What is "One Thing"?

One thing means one level of abstraction:

Does one thing:

def calculate_total_price(items, tax_rate):
    """Calculate total price of items including tax."""
    subtotal = sum(item.price * item.quantity for item in items)
    tax = subtotal * tax_rate
    return subtotal + tax

Single purpose: price calculation. All statements at same abstraction level (arithmetic).


Does multiple things:

def handle_order(order_data, user_id):
    """
    Process order:
    - Validate order data
    - Calculate total with tax
    - Apply discount codes
    - Check inventory
    - Create order record
    - Send confirmation email
    - Update user history
    - Return confirmation
    """
    validated = validate_order_data(order_data, user_id)  # Thing 1
    subtotal = calculate_subtotal(validated["items"])     # Thing 2
    discount = apply_discount(subtotal, validated.get("discount_code"))  # Thing 3
    tax = calculate_tax(subtotal - discount, validated["tax_rate"])      # Thing 4
    total = subtotal - discount + tax                      # Thing 5
    check_inventory(validated["items"])                    # Thing 6
    order_record = create_order_record(...)                # Thing 7
    send_confirmation_email(...)                           # Thing 8
    update_user_history(user_id, order_record["order_id"]) # Thing 9
    return {...}  # Thing 10

Description has 8 "and"s. Does 10 different things. Violates single responsibility.

How to Extract Routines

Technique 1: Extract by Responsibility

Group related statements, extract into focused routine:

Before (orchestrator does everything):

def handle_order(order_data, user_id):
    # Validation (lines 1-10)
    validated = validate_order_data(order_data, user_id)

    # Pricing (lines 11-15)
    subtotal = calculate_subtotal(validated["items"])
    discount = apply_discount(subtotal, validated.get("discount_code"))
    tax = calculate_tax(subtotal - discount, validated["tax_rate"])
    total = subtotal - discount + tax

    # Inventory (lines 16-20)
    check_inventory(validated["items"])

    # Persistence (lines 21-30)
    order_record = create_order_record(...)

    # Notifications (lines 31-35)
    send_confirmation_email(...)
    update_user_history(user_id, order_record["order_id"])

    return {...}

After (each phase is focused routine):

def handle_order(order_data, user_id):
    """Single responsibility: Orchestrate order processing."""
    validated_order = validate_order_request(order_data, user_id)
    pricing = calculate_order_pricing(validated_order)
    verify_inventory_available(validated_order)
    order = create_and_save_order(validated_order, pricing, user_id)
    send_order_notifications(order)
    return create_confirmation_response(order, pricing)

def validate_order_request(order_data, user_id):
    """Single responsibility: Validate order data."""
    # Just validation

def calculate_order_pricing(validated_order):
    """Single responsibility: Calculate prices."""
    # Just pricing math

def verify_inventory_available(validated_order):
    """Single responsibility: Check inventory."""
    # Just inventory check

def create_and_save_order(validated_order, pricing, user_id):
    """Single responsibility: Persist order."""
    # Just database operations

def send_order_notifications(order):
    """Single responsibility: Send notifications."""
    # Just email/notifications

Each routine now has single, clear purpose.

Technique 2: Extract Levels of Abstraction

If routine mixes high and low-level operations, extract low-level:

Mixed abstraction levels:

def process_report():
    # High level
    data = fetch_data()

    # LOW level detail
    for i in range(len(data)):
        if data[i] is not None and data[i] > 0:
            normalized = (data[i] - min_val) / (max_val - min_val)
            data[i] = normalized

    # High level
    generate_output(data)

Consistent abstraction:

def process_report():
    # All high level
    data = fetch_data()
    normalized_data = normalize_values(data)  # Low-level extracted
    generate_output(normalized_data)

def normalize_values(data):
    # Low-level details isolated here
    result = []
    for value in data:
        if value is not None and value > 0:
            normalized = (value - min_val) / (max_val - min_val)
            result.append(normalized)
    return result

Technique 3: Extract Complex Conditions

If conditional logic is complex, extract to well-named boolean function:

Complex inline condition:

if (user.age >= 18 and user.has_account and
    user.account_balance > minimum and not user.is_suspended and
    user.verified_email):
    allow_purchase()

Extracted condition:

if is_eligible_for_purchase(user):
    allow_purchase()

def is_eligible_for_purchase(user):
    """Single responsibility: Determine purchase eligibility."""
    return (user.age >= 18 and
            user.has_account and
            user.account_balance > minimum and
            not user.is_suspended and
            user.verified_email)

Benefits: Name explains WHAT checking, function explains HOW.

Quick Reference

Sign Routine Needs FocusExtraction Technique
Description has "and"Extract each responsibility
Routine > 200 linesExtract logical sections
Parameters > 7Group related params, extract
Hard to nameClarify purpose, split if multiple
Hard to testExtract testable pieces
Mixed abstraction levelsExtract low-level details
Deep nestingExtract nested logic
Long parameter listExtract to class or group params
Does A, B, C, DExtract B, C, D into focused routines

Functional Cohesion

The gold standard: Routine does one thing and only that thing.

Levels of Cohesion (Worst to Best)

  1. Coincidental - Unrelated things grouped together (avoid)
  2. Logical - Related things but different operations (weak)
  3. Temporal - Things done at same time (weak)
  4. Procedural - Things done in sequence (medium)
  5. Communicational - Work on same data (medium)
  6. Sequential - Output of one is input to next (good)
  7. Functional - Do ONE thing completely (best)

Always aim for functional cohesion.

Examples of Cohesion Types

❌ Coincidental (worst):

def miscellaneous_functions():
    initialize_printer()
    calculate_payroll()
    sort_personnel_records()
    # Unrelated things in one routine - terrible

⚠️ Temporal (weak):

def startup():
    initialize_database()
    initialize_ui()
    initialize_logging()
    # Related by WHEN (startup), not by WHAT

✅ Functional (best):

def calculate_employee_pay(employee, hours_worked):
    # Does ONE thing: calculate pay
    hourly_rate = employee.rate
    gross_pay = hourly_rate * hours_worked
    deductions = calculate_deductions(gross_pay)
    return gross_pay - deductions

Naming as a Diagnostic

Routine name reveals focus:

NameFocus Assessment
calculateTotal()
✅ Focused - one clear purpose
processData()
❌ Vague - what processing?
getUserAndValidate()
❌ Two things ("and" in name)
initializeSystemData()
⚠️ Might be multiple things
handleUserRegistrationAndWelcomeEmail()
❌ Obviously two things

If you struggle to name a routine clearly, it probably does too many things.

Extract until naming is easy.

Parameter Count Guideline

Research shows: Routines with > 7 parameters correlate with higher error rates.

Why? Many parameters suggest routine is doing too much.

Too many parameters:

def create_order(user_id, items, shipping_addr, billing_addr,
                 discount_code, tax_rate, payment_method, notes):
    # 8 parameters - probably doing too much

Group related parameters:

def create_order(user_id, order_details):
    # 2 parameters - order_details is an object containing the data

Or extract responsibilities:

def create_order(validated_order, calculated_pricing):
    # Validation and pricing are separate responsibilities
    # This routine just creates the order record

Length Guidelines

No hard limit, but:

  • Most routines: < 50 lines
  • Review if > 100 lines
  • Strong signal to extract if > 200 lines

Exception: Generated code, complex state machines, extensive error handling

Question to ask: Can I extract logical sections without making code worse?

When to Extract

Extract When:

  1. Multiple responsibilities - Routine does A and B and C
  2. Mixed abstraction levels - High-level calls mixed with low-level details
  3. Complex section - One part is complex, rest is simple (extract complex part)
  4. Duplicate logic - Same code appears in multiple places
  5. Hard to test - Doing too much to test atomically
  6. Poor naming - Can't name it clearly (probably unfocused)
  7. Long routine - Natural extraction points exist

Don't Extract When:

  1. Simpler inline - Extraction adds more complexity than it removes
  2. Used once - No duplication, no complexity reduction
  3. No natural boundary - Arbitrary split would make code harder to understand

Default: When in doubt, extract. Extraction rarely makes code worse.

Extraction Patterns

Pattern 1: Extract Complex Calculation

# ✅ Extract complex logic
def calculate_mortgage_payment(principal, annual_rate, years):
    monthly_rate = convert_to_monthly_rate(annual_rate)
    num_payments = years * 12
    return calculate_monthly_payment(principal, monthly_rate, num_payments)

def convert_to_monthly_rate(annual_rate):
    return annual_rate / 12 / 100

def calculate_monthly_payment(principal, monthly_rate, num_payments):
    return principal * (monthly_rate * (1 + monthly_rate)**num_payments) / \
           ((1 + monthly_rate)**num_payments - 1)

Pattern 2: Extract Validation

# ✅ Extract validation to focused routine
def process_payment(payment_data):
    validate_payment_data(payment_data)  # Extracted
    return execute_payment_transaction(payment_data)

def validate_payment_data(data):
    """Single responsibility: validation."""
    # All validation logic here

Pattern 3: Extract by Abstraction Level

# ✅ High-level routine calls lower-level focused routines
def generate_report():
    # High-level orchestration
    data = collect_report_data()
    analysis = analyze_data(data)
    formatted_report = format_report_output(analysis)
    save_report(formatted_report)
    return formatted_report

Common Mistakes

❌ God function (does everything):

def handle_user_request():
    # Validation
    # Authentication
    # Authorization
    # Business logic
    # Database operations
    # Logging
    # Email sending
    # Response formatting
    # 300 lines doing 8 different things

✅ Focused orchestrator:

def handle_user_request(request):
    """Single responsibility: Orchestrate request handling."""
    user = authenticate_user(request)
    authorize_action(user, request.action)
    result = execute_business_logic(request, user)
    save_to_database(result)
    send_notifications(user, result)
    return format_response(result)

❌ Mixed abstraction levels:

def process_order(order):
    validate_order(order)  # High level

    # Low level details mixed in
    for item in order.items:
        db.execute("UPDATE inventory SET quantity = quantity - ? WHERE id = ?",
                   (item.quantity, item.product_id))

    send_confirmation(order)  # High level

Consistent abstraction:

def process_order(order):
    """High-level orchestration."""
    validate_order(order)
    update_inventory(order.items)  # Low-level extracted
    send_confirmation(order)

def update_inventory(items):
    """Low-level: Update database."""
    for item in items:
        db.execute("UPDATE inventory SET quantity = quantity - ? WHERE id = ?",
                   (item.quantity, item.product_id))

❌ "Utility" routine (does miscellaneous things):

def utils():
    # Initializes printer
    # Calculates payroll
    # Sorts records
    # Unrelated things - coincidental cohesion (worst)

Focused routines:

def initialize_printer(): ...
def calculate_payroll(): ...
def sort_personnel_records(): ...

The "And" Test

Listen to your description of the routine:

❌ "This routine validates the input AND calculates the result AND sends email" → Three responsibilities. Extract 2 of them.

❌ "This gets user data AND formats it for display" → Two responsibilities (retrieval and formatting). Extract formatting.

✅ "This calculates the shipping cost based on weight and destination" → One responsibility (calculation). The "and" lists parameters, not responsibilities.

If description has "and" connecting actions → routine does too many things.

Quick Decision Tree

Need to write/review a routine
  ↓
Does it do ONE thing?
  ├─ YES → Good, keep it focused
  └─ NO → Does description have "and"?
      ├─ YES → Extract responsibilities
      └─ Mixed abstraction levels?
          ├─ YES → Extract low-level details
          └─ > 200 lines?
              ├─ YES → Find natural boundaries, extract
              └─ > 7 parameters?
                  ├─ YES → Group params or extract
                  └─ Hard to name?
                      ├─ YES → Clarify purpose, maybe split
                      └─ Keep as-is, it's focused

Extraction Example

Original (unfocused):

def handle_order(order_data, user_id):
    # Validate (responsibility 1)
    if not order_data.get("items"):
        raise ValueError("No items")
    if not user_id:
        raise ValueError("No user")

    # Calculate pricing (responsibility 2)
    subtotal = sum(item["price"] * item["qty"] for item in order_data["items"])
    tax = subtotal * 0.08
    total = subtotal + tax

    # Check inventory (responsibility 3)
    for item in order_data["items"]:
        if inventory[item["id"]] < item["qty"]:
            raise InventoryError()

    # Create record (responsibility 4)
    order_id = f"ORD-{datetime.now().isoformat()}"
    order = {"id": order_id, "user_id": user_id, "total": total}
    save_order(order)

    # Send email (responsibility 5)
    send_email(user_id, f"Order {order_id} confirmed")

    return order

Extracted (focused routines):

def handle_order(order_data, user_id):
    """Single responsibility: Orchestrate order flow."""
    validate_order_request(order_data, user_id)
    pricing = calculate_pricing(order_data)
    verify_inventory(order_data)
    order = create_order(order_data, pricing, user_id)
    notify_user(order, user_id)
    return order

def validate_order_request(order_data, user_id):
    """Single responsibility: Validation."""
    if not order_data.get("items"):
        raise ValueError("No items")
    if not user_id:
        raise ValueError("No user")

def calculate_pricing(order_data):
    """Single responsibility: Pricing."""
    subtotal = sum(item["price"] * item["qty"] for item in order_data["items"])
    tax = subtotal * 0.08
    return {"subtotal": subtotal, "tax": tax, "total": subtotal + tax}

def verify_inventory(order_data):
    """Single responsibility: Inventory check."""
    for item in order_data["items"]:
        if inventory[item["id"]] < item["qty"]:
            raise InventoryError(f"Insufficient inventory for {item['id']}")

def create_order(order_data, pricing, user_id):
    """Single responsibility: Order creation."""
    order_id = f"ORD-{datetime.now().isoformat()}"
    order = {"id": order_id, "user_id": user_id, "total": pricing["total"]}
    save_order(order)
    return order

def notify_user(order, user_id):
    """Single responsibility: Notification."""
    send_email(user_id, f"Order {order['id']} confirmed")

Benefits:

  • Each routine has single, testable responsibility
  • Can modify pricing without touching validation
  • Can reuse validate_order_request elsewhere
  • Easy to understand each piece in isolation
  • Clear names describe exactly what each does

Benefits of Focused Routines

1. Easier to Understand

Small, focused routines are easier to comprehend:

  • Can understand without seeing rest of system
  • Name tells you what it does
  • Implementation is short enough to hold in mind

2. Easier to Test

# ✅ Easy to test focused routine
def calculate_tax(amount, rate):
    return amount * rate

# Test with various inputs, done

# ❌ Hard to test unfocused routine
def handle_order(...):
    # Does 8 things - need to test all 8 in combination
    # Need mocks for email, database, inventory, etc.

3. Easier to Modify

Focused routines have clear boundaries:

  • Change pricing logic → modify calculate_pricing only
  • Change validation → modify validate_order_request only
  • Changes don't ripple unexpectedly

4. Easier to Reuse

# ✅ Can reuse focused routines
def handle_order(...):
    validate_order_request(...)  # Reusable

def handle_return(...):
    validate_order_request(...)  # Same validation, different context

5. Reduces Complexity

Breaking into focused pieces makes each piece simpler:

  • One routine: 200 lines, complex
  • Four routines: 50 lines each, simple

Mental load: Understand 50 lines vs understand 200 lines.

When Routine is Appropriately Long

Some routines are naturally longer:

  1. Extensive but straightforward validation - Many simple checks in sequence
  2. State machines - Many states and transitions
  3. Generated code - Auto-generated switch statements
  4. Linear algorithms - Many sequential steps with no natural boundaries

Question: Are there natural extraction points that would improve clarity?

If no → keep as-is. If yes → extract.

Verification Checklist

For each routine, check:

  • Does ONE thing (functional cohesion)?
  • Description has no "and" connecting different actions?
  • Name clearly describes the one thing it does?
  • All statements at consistent abstraction level?
  • Parameters < 7 (or grouped into object)?
  • Length natural for its purpose (not artificially inflated)?
  • Easy to write test case?
  • Can understand without seeing rest of system?

If any "no" → consider extracting.

Real-World Impact

From Code Complete:

  • Functional cohesion is strongest, most maintainable
  • Routines doing one thing are easiest to understand
  • Most routines should be simple enough to name clearly
  • Parameter count > 7 correlates with higher error rates

From baseline testing:

  • Agent extracted helper functions (good instinct!)
  • BUT orchestrator still did 8-10 things
  • Each helper was focused, but main routine wasn't
  • Grade: C (good instinct, incomplete application)

With this skill: Both helpers AND orchestrators stay focused.

Integration with Other Skills

For extracting during refactoring: See skills/designing-before-coding - sometimes one pseudocode line explodes to many code lines, indicating need to extract

For complexity reduction: See skills/architecture/reducing-complexity - focused routines reduce mental juggling required