Claude-skill-registry Keeping Routines Focused
Each routine does one thing and does it well - extract when routines have multiple responsibilities
git clone https://github.com/majiayu000/claude-skill-registry
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"
skills/data/keeping-routines-focused/SKILL.mdKeeping 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 Focus | Extraction Technique |
|---|---|
| Description has "and" | Extract each responsibility |
| Routine > 200 lines | Extract logical sections |
| Parameters > 7 | Group related params, extract |
| Hard to name | Clarify purpose, split if multiple |
| Hard to test | Extract testable pieces |
| Mixed abstraction levels | Extract low-level details |
| Deep nesting | Extract nested logic |
| Long parameter list | Extract to class or group params |
| Does A, B, C, D | Extract 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)
- Coincidental - Unrelated things grouped together (avoid)
- Logical - Related things but different operations (weak)
- Temporal - Things done at same time (weak)
- Procedural - Things done in sequence (medium)
- Communicational - Work on same data (medium)
- Sequential - Output of one is input to next (good)
- 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:
| Name | Focus Assessment |
|---|---|
| ✅ Focused - one clear purpose |
| ❌ Vague - what processing? |
| ❌ Two things ("and" in name) |
| ⚠️ Might be multiple things |
| ❌ 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:
- Multiple responsibilities - Routine does A and B and C
- Mixed abstraction levels - High-level calls mixed with low-level details
- Complex section - One part is complex, rest is simple (extract complex part)
- Duplicate logic - Same code appears in multiple places
- Hard to test - Doing too much to test atomically
- Poor naming - Can't name it clearly (probably unfocused)
- Long routine - Natural extraction points exist
Don't Extract When:
- Simpler inline - Extraction adds more complexity than it removes
- Used once - No duplication, no complexity reduction
- 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:
- Extensive but straightforward validation - Many simple checks in sequence
- State machines - Many states and transitions
- Generated code - Auto-generated switch statements
- 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