一键导入
keeping-routines-focused
Each routine does one thing and does it well - extract when routines have multiple responsibilities
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Each routine does one thing and does it well - extract when routines have multiple responsibilities
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Fork, clone to ~/.clank, run installer, edit CLAUDE.md
RED-GREEN-REFACTOR for process documentation - baseline without skill, write addressing failures, iterate closing loopholes
Skills wiki intro - mandatory workflows, search tool, brainstorming triggers
Interactive idea refinement using Socratic method to develop fully-formed designs
Execute detailed plans in batches with review checkpoints
Execute implementation plan by dispatching fresh subagent for each task, with code review between tasks
| name | Keeping Routines Focused |
| description | Each routine does one thing and does it well - extract when routines have multiple responsibilities |
| when_to_use | When writing any function or method. When routine does multiple things. When routine description has "and" in it. When routine is hard to name. When routine is longer than 200 lines. When parameter list exceeds 7 parameters. When refactoring complex code. When god function exists. When function does too much. When tests are hard to write for a function. When mixed abstraction levels in one routine. When code review flags "too complex" or "does too many things". When cohesion is weak. When violating single responsibility principle. When function has many local variables. |
| version | 1.0.0 |
| languages | all |
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.
Proactively (writing new code):
Reactively (improving existing code):
Warning signs routine needs focus:
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.
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.
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
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.
| 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 |
The gold standard: Routine does one thing and only that thing.
Always aim for functional cohesion.
❌ 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
Routine name reveals focus:
| Name | Focus 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.
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
No hard limit, but:
Exception: Generated code, complex state machines, extensive error handling
Question to ask: Can I extract logical sections without making code worse?
Default: When in doubt, extract. Extraction rarely makes code worse.
# ✅ 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)
# ✅ 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
# ✅ 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
❌ 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(): ...
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.
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
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:
Small, focused routines are easier to comprehend:
# ✅ 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.
Focused routines have clear boundaries:
# ✅ Can reuse focused routines
def handle_order(...):
validate_order_request(...) # Reusable
def handle_return(...):
validate_order_request(...) # Same validation, different context
Breaking into focused pieces makes each piece simpler:
Mental load: Understand 50 lines vs understand 200 lines.
Some routines are naturally longer:
Question: Are there natural extraction points that would improve clarity?
If no → keep as-is. If yes → extract.
For each routine, check:
If any "no" → consider extracting.
From Code Complete:
From baseline testing:
With this skill: Both helpers AND orchestrators stay focused.
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