Skip to main content

refactoring-techniques

Catalog of refactoring techniques from refactoring.guru - how to apply Extract Method, Move Field, Replace Conditional, and 60+ other refactorings

Ir a la instalación

Datos de origen

Repositorio
ROCm/rocprofiler-systems-skills
Última actividad en el origen
16 de marzo de 2026 a las 11:36
Idioma detectado de SKILL.md
inglés
Estrellas
4
Forks
0

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
refactoring-techniques
description
Catalog of refactoring techniques from refactoring.guru - how to apply Extract Method, Move Field, Replace Conditional, and 60+ other refactorings
# Refactoring Techniques Catalog Comprehensive reference of refactoring techniques for transforming code while preserving behavior. Based on [Refactoring.Guru Techniques](https://refactoring.guru/refactoring/techniques). <IMPORTANT> This skill is a **reference catalog** for applying refactorings. It is used by: - `planning-refactor` when implementing improvements - `code-smells` to suggest fixes for detected smells - Standalone refactoring assistance **Cross-Reference:** See `code-smells` skill for detecting WHAT to fix. This skill shows HOW to fix it. </IMPORTANT> ## When to Use | Context | Trigger | |---------|---------| | **Planning Refactor** | Need specific technique to fix identified smell | | **Code Review** | Suggesting improvements during PR review | | **Learning** | User asks how to apply a specific refactoring | | **Quick Fix** | User wants to apply a refactoring immediately | ## Quick Reference: Smell to Refactoring | Code Smell | Recommended Refactorings | |------------|-------------------------| | Long Method | Extract Method, Replace Temp with Query, Decompose Conditional | | Large Class | Extract Class, Extract Subclass, Extract Interface | | Long Parameter List | Introduce Parameter Object, Preserve Whole Object | | Duplicate Code | Extract Method, Pull Up Method, Form Template Method | | Feature Envy | Move Method, Extract Method | | Switch Statements | Replace Conditional with Polymorphism, Replace Type Code with Subclasses | | Data Clumps | Extract Class, Introduce Parameter Object | | Primitive Obsession | Replace Data Value with Object, Replace Type Code with Class | | Shotgun Surgery | Move Method, Move Field, Inline Class | | Divergent Change | Extract Class | | Message Chains | Hide Delegate | | Middle Man | Remove Middle Man | | Refused Bequest | Replace Inheritance with Delegation | --- ## Category 1: Composing Methods Techniques for correctly structuring methods. Long methods are often the root of many problems. ### Extract Method | Aspect | Details | |--------|---------| | **Impact** | High - Most frequently used refactoring | | **Risk** | Low | | **Fixes** | Long Method, Duplicate Code, Comments | **Problem:** Code fragment that can be logically grouped together. **Solution:** Create a new method with a descriptive name and move the fragment there. **Steps:** 1. Create new method named after WHAT it does (not HOW) 2. Copy the code fragment to the new method 3. Look for local variables used only within the fragment - make them local to new method 4. Pass external variables as parameters 5. If extracted code modifies a variable needed later, return it 6. Replace original fragment with method call **C++ Example:** ```cpp // BEFORE void print_invoice(const Invoice& inv) { // Print header std::cout << "================\n"; std::cout << "INVOICE #" << inv.number << "\n"; std::cout << "Date: " << inv.date << "\n"; std::cout << "================\n"; // Print items for (const auto& item : inv.items) { std::cout << item.name << ": $" << item.price << "\n"; } // Calculate and print total double total = 0; for (const auto& item : inv.items) { total += item.price; } std::cout << "Total: $" << total << "\n"; } // AFTER void print_header(const Invoice& inv) { std::cout << "================\n"; std::cout << "INVOICE #" << inv.number << "\n"; std::cout << "Date: " << inv.date << "\n"; std::cout << "================\n"; } void print_items(const std::vector<Item>& items) { for (const auto& item : items) { std::cout << item.name << ": $" << item.price << "\n"; } } double calculate_total(const std::vector<Item>& items) { return std::accumulate(items.begin(), items.end(), 0.0, [](double sum, const Item& item) { return sum + item.price; }); } void print_invoice(const Invoice& inv) { print_header(inv); print_items(inv.items); std::cout << "Total: $" << calculate_total(inv.items) << "\n"; } ``` **Python Example:** ```python # BEFORE def print_invoice(inv): # Print header print("================") print(f"INVOICE #{inv.number}") print(f"Date: {inv.date}") print("================") # Print items and calculate total total = 0 for item in inv.items: print(f"{item.name}: ${item.price}") total += item.price print(f"Total: ${total}") # AFTER def print_header(inv): print("================") print(f"INVOICE #{inv.number}") print(f"Date: {inv.date}") print("================") def print_items(items): for item in items: print(f"{item.name}: ${item.price}") def calculate_total(items): return sum(item.price for item in items) def print_invoice(inv): print_header(inv) print_items(inv.items) print(f"Total: ${calculate_total(inv.items)}") ``` --- ### Inline Method | Aspect | Details | |--------|---------| | **Impact** | Low | | **Risk** | Low | | **Fixes** | Speculative Generality, excessive delegation | **Problem:** Method body is more obvious than the method itself. **Solution:** Replace method calls with the method content and delete the method. **Steps:** 1. Verify method is not overridden in subclasses 2. Find all calls to the method 3. Replace each call with the method body 4. Delete the method ```cpp // BEFORE int get_rating() { return more_than_five_late_deliveries() ? 2 : 1; } bool more_than_five_late_deliveries() { return late_deliveries_ > 5; } // AFTER int get_rating() { return late_deliveries_ > 5 ? 2 : 1; } ``` --- ### Extract Variable | Aspect | Details | |--------|---------| | **Impact** | Medium | | **Risk** | Low | | **Fixes** | Complex expressions, Comments | **Problem:** Hard-to-understand expression. **Solution:** Place the expression result in a self-explanatory variable. **Steps:** 1. Insert a new variable and assign the expression to it 2. Replace the original expression with the variable 3. Repeat for other occurrences of the same expression ```cpp // BEFORE if (platform.find("MAC") != std::string::npos && browser.find("IE") != std::string::npos && was_initialized() && resize > 0) { // ... } // AFTER bool is_mac = platform.find("MAC") != std::string::npos; bool is_ie = browser.find("IE") != std::string::npos; bool was_resized = resize > 0; if (is_mac && is_ie && was_initialized() && was_resized) { // ... } ``` --- ### Replace Temp with Query | Aspect | Details | |--------|---------| | **Impact** | Medium | | **Risk** | Low | | **Fixes** | Long Method (preparation for Extract Method) | **Problem:** Temporary variable storing an expression result for later use. **Solution:** Move the expression to a new method and call the method instead of using the variable. **Steps:** 1. Ensure the variable is only assigned once 2. Extract the expression into a new method 3. Replace all uses of the variable with method calls 4. Remove the variable declaration ```cpp // BEFORE double calculate_total() { double base_price = quantity_ * item_price_; if (base_price > 1000) { return base_price * 0.95; } return base_price * 0.98; } // AFTER double base_price() const { return quantity_ * item_price_; } double calculate_total() { if (base_price() > 1000) { return base_price() * 0.95; } return base_price() * 0.98; } ``` --- ### Split Temporary Variable | Aspect | Details | |--------|---------| | **Impact** | Medium | | **Risk** | Low | | **Fixes** | Variable reuse, unclear intent | **Problem:** Local variable used for multiple unrelated purposes. **Solution:** Create separate variables for each purpose. ```cpp // BEFORE double temp = 2 * (height_ + width_); std::cout << "Perimeter: " << temp << "\n"; temp = height_ * width_; std::cout << "Area: " << temp << "\n"; // AFTER double perimeter = 2 * (height_ + width_); std::cout << "Perimeter: " << perimeter << "\n"; double area = height_ * width_; std::cout << "Area: " << area << "\n"; ``` --- ### Remove Assignments to Parameters | Aspect | Details | |--------|---------| | **Impact** | Medium | | **Risk** | Low | | **Fixes** | Confusing parameter modification | **Problem:** Value assigned to a parameter inside method body. **Solution:** Use a local variable instead of the parameter. ```cpp // BEFORE int discount(int input_val, int quantity) { if (quantity > 50) { input_val -= 2; // Modifying parameter! } return input_val; } // AFTER int discount(int input_val, int quantity) { int result = input_val; if (quantity > 50) { result -= 2; } return result; } ``` --- ### Replace Method with Method Object | Aspect | Details | |--------|---------| | **Impact** | High | | **Risk** | Medium | | **Fixes** | Long Method with intertwined local variables | **Problem:** Long method where local variables prevent extraction. **Solution:** Transform the method into a separate class where locals become fields. **Steps:** 1. Create a new class named after the method 2. Create a private field for the original object and each local variable/parameter 3. Create a constructor that initializes all fields 4. Copy the method body to a `compute()` method in the new class 5. Replace original method with creation of method object and call to `compute()` ```cpp // BEFORE class Order {
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub