Skip to main content

keeping-routines-focused

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

Datos de origen

Repositorio
obra/clank
Última actividad en el origen
7 de octubre de 2025 a las 17:04
Idioma detectado de SKILL.md
inglés
Estrellas
41
Forks
27

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
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
# 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:** ```python 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:** ```python 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):** ```python 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):** ```python 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:** ```python 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:** ```python 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:** ```python 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:** ```python 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) 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):** ```python def miscellaneous_functions(): initialize_printer() calculate_payroll() sort_personnel_records() # Unrelated things in one routine - terrible ``` **⚠️ Temporal (weak):** ```python def startup(): initialize_database() initialize_ui() initialize_logging() # Related by WHEN (startup), not by WHAT ``` **✅ Functional (best):** ```python 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 | |------|------------------| | `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:** ```python 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:** ```python def create_order(user_id, order_details): # 2 parameters - order_details is an object containing the data ``` ✅ **Or extract responsibilities:** ```python 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 ```python # ✅ 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 ```python # ✅ 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 ```python # ✅ 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):** ```python def handle_user_request(): # Validation # Authentication # Authorization # Business logic # Database operations # Logging # Email sending # Response formatting # 300 lines doing 8 different things ``` **✅ Focused orchestrator:** ```python 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:** ```python def process_order(order): validate_order(order) # High level # Low level details mixed in
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub