Refactoring Catalog (Multi-Language)
A comprehensive, technique-by-technique catalog of refactoring best practices for any language, sourced from Martin Fowler's Refactoring: Improving the Design of Existing Code (2nd Edition) and Alexander Shvets' Refactoring in Java (Refactoring Guru). Adapted for Python, TypeScript, Go, and Rust with idiomatic examples.
Step 0: Detect Language
Before applying any technique, detect the project's stack:
| Project File |
Language |
Idiom Style |
pom.xml / build.gradle |
Java |
OOP, Stream API |
pyproject.toml / requirements.txt / setup.py |
Python |
Duck typing, comprehensions |
package.json + tsconfig.json |
TypeScript |
Functional-OOP hybrid |
package.json (no tsconfig) |
JavaScript |
Prototype-based, functional |
*.csproj |
C# |
OOP, LINQ |
go.mod |
Go |
Composition, implicit interfaces |
build.gradle.kts |
Kotlin |
OOP + functional |
Gemfile |
Ruby |
Duck typing, open classes |
composer.json |
PHP |
OOP |
Cargo.toml |
Rust |
Ownership, traits, no inheritance |
Package.swift |
Swift |
Protocol-oriented |
If the language is Java, apply techniques with Java OOP, Stream API where appropriate, and the project's detected Java version constraints. Use references/java-notes.md for Java-specific constraints and the Java completion gate.
Language Support Matrix
| Concept |
Python |
TypeScript |
Go |
Rust |
| Class / struct |
class |
class |
struct + methods |
struct + impl |
| Inheritance |
class Child(Parent) |
extends |
Embedding (no inheritance) |
Traits (no inheritance) |
| Interface / contract |
Protocol / ABC |
interface |
interface (implicit) |
trait |
| Encapsulation |
_private convention |
private keyword |
Unexported (lowercase) |
Private by default, pub |
| Polymorphism |
Duck typing + ABC |
Interfaces + classes |
Implicit interfaces |
Trait objects + generics |
| Generics |
typing.Generic[T] |
<T> |
[T any] |
<T: Trait> |
| Error handling |
Exceptions |
Exceptions |
Error values (error) |
Result<T, E> |
| Null safety |
None / Optional[T] |
null / undefined / ? |
nil (zero values) |
Option<T> |
| Collections pipeline |
Comprehensions / generators |
Array methods (.map, .filter) |
for range (no pipeline) |
Iterator chain (.filter().map()) |
| Pattern matching |
match (3.10+) |
switch (no pattern matching) |
switch (no pattern matching) |
match (exhaustive) |
| Factory pattern |
@classmethod / module function |
Static method / function |
NewXxx() function |
Type::new() associated fn |
| Builder pattern |
__init__ + kwargs / dataclass |
Fluent builder class |
Functional options |
Builder with consuming self |
For detailed concept-to-language mappings, see references/language-idioms.md.
Core Philosophy
Refactoring is the process of changing the internal structure of code without altering its observable behavior. It is a disciplined technique, not a random cleanup. The golden rule is: Cover → Modify → Refactor (always have tests before you start).
How to Use This Skill
- Detect the language (Step 0 above)
- Diagnose first: Identify the code smell (see
techniques/00-code-smells-diagnostic.md)
- Check applicability: See
references/language-applicability.md for technique availability per language
- Select technique: Each smell maps to one or more refactoring techniques; when several compete, use
references/selection-heuristics.md for the ordered decision rules
- Read the technique file: Each technique has multi-language examples (Python, TypeScript, Go, Rust)
- For Java: Read
references/java-notes.md, use Java OOP/Stream idioms, honor Java 8 versus Java 11+ API availability, and finish with the Java completion gate
- For language idiom mapping: See
references/language-idioms.md
- Apply incrementally: Small steps, test after each change, commit frequently
Technique Categories
The techniques are organized in 7 groups. Each technique has its own file in the techniques/ directory.
Group 1: Composing Methods (techniques/01-XX)
Techniques for building clean, well-structured methods. The foundation of all refactoring.
01-extract-method.md — Extract a code fragment into a named function
02-inline-method.md — Replace a function call with the function body
03-extract-variable.md — Give a name to a complex expression
04-inline-variable.md — Remove a variable that adds no clarity
05-replace-temp-with-query.md — Replace temp variables with function calls
06-replace-method-with-method-object.md — Turn a complex function into its own class/struct
07-substitute-algorithm.md — Replace an algorithm with a clearer version
Group 2: Moving Features (techniques/02-XX)
Techniques for placing code where it truly belongs.
08-move-method.md — Move a function to where it has more cohesion
09-move-field.md — Move a field to the type that uses it most
10-extract-class.md — Split a type with multiple responsibilities
11-inline-class.md — Merge a type that does too little
12-hide-delegate.md — Encapsulate chain navigation behind a simpler interface
13-remove-middle-man.md — Remove unnecessary delegation
14-move-statements.md — Move statements into/out of functions, slide statements
15-split-loop.md — Separate a loop that does multiple things
16-replace-loop-with-pipeline.md — Use declarative pipelines instead of imperative loops
17-remove-dead-code.md — Delete unused code
Group 3: Organizing Data (techniques/03-XX)
Techniques for enriching data with behavior and protecting internal state.
18-encapsulate-variable.md — Wrap data access with getters/functions
19-encapsulate-record.md — Convert data structures into objects/structs
20-encapsulate-collection.md — Protect collections from external mutation
21-replace-primitive-with-object.md — Create domain types instead of using raw primitives
22-split-variable.md — Give each purpose its own variable
23-rename-field.md — Improve field names for clarity
24-replace-derived-variable-with-query.md — Calculate values on demand
25-change-reference-to-value.md — Make objects immutable (Value Objects)
26-change-value-to-reference.md — Share a single instance across consumers
27-replace-type-code-with-subclasses.md — Convert type codes to polymorphic hierarchy
Group 4: Simplifying Conditionals (techniques/04-XX)
Techniques for taming conditional complexity.
28-decompose-conditional.md — Name condition and branches
29-consolidate-conditional.md — Merge related conditions
30-replace-nested-conditional-with-guard-clauses.md — Early returns for special cases
31-replace-conditional-with-polymorphism.md — Use polymorphism instead of switch/if-type
32-introduce-special-case.md — Null Object pattern for default behavior
33-introduce-assertion.md — Document invariants with executable assertions
34-replace-control-flag.md — Replace boolean flags with break/return
Group 5: Simplifying Method Calls / API Design (techniques/05-XX)
Techniques for building self-documenting interfaces.
35-change-function-declaration.md — Rename functions and change parameters
36-introduce-parameter-object.md — Group related parameters into an object
37-parameterize-function.md — Unify similar functions with a parameter
38-remove-flag-argument.md — Replace boolean params with named functions
39-preserve-whole-object.md — Pass the object instead of extracted values
40-replace-parameter-with-query.md — Let the function calculate what it needs
41-replace-query-with-parameter.md — Pass value as param for purity/testability
42-remove-setting-method.md — Make properties read-only
43-replace-constructor-with-factory.md — Use factory functions for flexible creation
44-replace-function-with-command.md — Encapsulate function as object
45-separate-query-from-modifier.md — CQS: separate reads from writes
Group 6: Dealing with Generalization (techniques/06-XX)
Techniques for refactoring type hierarchies and shared behavior.
46-pull-up-method.md — Move duplicated functions to shared parent/trait/interface
47-push-down-method.md — Move specialized functions to specific types
48-pull-up-constructor-body.md — Unify constructor/initialization logic
49-extract-superclass.md — Create common parent for shared behavior
50-extract-interface.md — Define a contract without implementation
51-collapse-hierarchy.md — Merge unnecessary hierarchy levels
52-form-template-method.md — Template Method pattern
53-replace-subclass-with-delegate.md — Composition over inheritance
54-replace-superclass-with-delegate.md — Replace extends with has-a
55-replace-inheritance-with-delegation.md — General inheritance to delegation
Group 7: Additional Techniques (techniques/07-XX)
Cross-cutting techniques from both sources.
56-combine-functions-into-class.md — Group functions that share data
57-combine-functions-into-transform.md — Enrich read-only data
58-split-phase.md — Separate code into processing phases
59-introduce-foreign-method.md — Extend third-party types you can't modify
60-introduce-local-extension.md — Wrapper or subclass for library extension
61-replace-error-code-with-exception.md — Modernize error handling
62-replace-exception-with-test.md — Don't use exceptions for control flow
Diagnostic Guide
Start with techniques/00-code-smells-diagnostic.md to identify which techniques apply to your code. The diagnostic maps 24 code smells to their recommended refactoring techniques.
Applying the Skill
When given code to refactor:
- Detect the language (Step 0)
- Read
techniques/00-code-smells-diagnostic.md to identify the smells present
- For each identified smell, read the corresponding technique file(s)
- Check
references/language-applicability.md — if the technique doesn't apply to the target language, the table shows the alternative
- Apply techniques in small steps, always testing between changes
- Provide idiomatic examples for the detected language
- Explain WHY each refactoring improves the code, not just HOW to do it
- For Java, report the
references/java-notes.md Java completion gate verdict
- For language-specific idiom translations, consult
references/language-idioms.md
Key Principles
These principles underpin every technique in the catalog:
- Names matter more than length — a well-named 1-line function is better than an inline expression
- Small steps — extract small fragments, test, commit. Never batch multiple changes
- Intention over implementation — code should communicate WHAT, not HOW
- Data and logic that change together should live together — cohesion is king
- Prefer composition over inheritance — delegation is more flexible than extends
- Immutability is a powerful preservative — immutable data is easier to reason about
- CQS (Command-Query Separation) — a function either returns a value or modifies state, never both
Reference Files
| File |
Content |
references/language-idioms.md |
Refactoring concept → {Python, TypeScript, Go, Rust} equivalents |
references/language-applicability.md |
62-technique × language applicability matrix with alternatives |
references/java-notes.md |
Java-specific constraints, Java 8 vs 11+ notes, and the Java completion gate |
references/selection-heuristics.md |
Ordered decision rules when several techniques compete: conditionals tree, smell directionality, falsifiable micro-tests, inheritance→delegation triggers |
references/technique-to-pattern.md |
Which refactoring techniques land on which GoF pattern (Kerievsky bridge) |
1---2name: refactor3description: Cross-language catalog of 62+ refactoring techniques based on Martin Fowler's "Refactoring" and Alexander Shvets' "Refactoring Guru". Detects the project's language automatically and provides idiomatic examples. Works with Java, Python, TypeScript, JavaScript, C#, Go, Kotlin, Ruby, PHP, Rust, Swift. Use this skill whenever the user asks to refactor code, improve code quality, eliminate code smells, simplify conditionals, restructure classes, improve API design, or apply any named refactoring technique. Also trigger when the user mentions code smells, legacy code improvement, clean code practices, SOLID principles, or asks "how can I improve this code". Even if the user just pastes code and asks for improvement suggestions, use this skill to identify applicable techniques. También se activa en castellano: "refactorizar", "refactorizar código", "mejorar este código", "malos olores del código", "olores de código", "código sucio", "limpiar código", "simplificar condicionales", "principios SOLID", "cómo mejorar es4license: MIT5---67# Refactoring Catalog (Multi-Language)89A comprehensive, technique-by-technique catalog of refactoring best practices for any language, sourced from Martin Fowler's *Refactoring: Improving the Design of Existing Code* (2nd Edition) and Alexander Shvets' *Refactoring in Java* (Refactoring Guru). Adapted for Python, TypeScript, Go, and Rust with idiomatic examples.1011## Step 0: Detect Language1213Before applying any technique, detect the project's stack:1415| Project File | Language | Idiom Style |16|---|---|---|17| `pom.xml` / `build.gradle` | Java | OOP, Stream API |18| `pyproject.toml` / `requirements.txt` / `setup.py` | Python | Duck typing, comprehensions |19| `package.json` + `tsconfig.json` | TypeScript | Functional-OOP hybrid |20| `package.json` (no tsconfig) | JavaScript | Prototype-based, functional |21| `*.csproj` | C# | OOP, LINQ |22| `go.mod` | Go | Composition, implicit interfaces |23| `build.gradle.kts` | Kotlin | OOP + functional |24| `Gemfile` | Ruby | Duck typing, open classes |25| `composer.json` | PHP | OOP |26| `Cargo.toml` | Rust | Ownership, traits, no inheritance |27| `Package.swift` | Swift | Protocol-oriented |2829If the language is **Java**, apply techniques with Java OOP, Stream API where appropriate, and the project's detected Java version constraints. Use `references/java-notes.md` for Java-specific constraints and the Java completion gate.3031## Language Support Matrix3233| Concept | Python | TypeScript | Go | Rust |34|---|---|---|---|---|35| Class / struct | `class` | `class` | `struct` + methods | `struct` + `impl` |36| Inheritance | `class Child(Parent)` | `extends` | Embedding (no inheritance) | Traits (no inheritance) |37| Interface / contract | `Protocol` / `ABC` | `interface` | `interface` (implicit) | `trait` |38| Encapsulation | `_private` convention | `private` keyword | Unexported (lowercase) | Private by default, `pub` |39| Polymorphism | Duck typing + ABC | Interfaces + classes | Implicit interfaces | Trait objects + generics |40| Generics | `typing.Generic[T]` | `<T>` | `[T any]` | `<T: Trait>` |41| Error handling | Exceptions | Exceptions | Error values (`error`) | `Result<T, E>` |42| Null safety | `None` / `Optional[T]` | `null` / `undefined` / `?` | `nil` (zero values) | `Option<T>` |43| Collections pipeline | Comprehensions / generators | Array methods (`.map`, `.filter`) | `for range` (no pipeline) | Iterator chain (`.filter().map()`) |44| Pattern matching | `match` (3.10+) | `switch` (no pattern matching) | `switch` (no pattern matching) | `match` (exhaustive) |45| Factory pattern | `@classmethod` / module function | Static method / function | `NewXxx()` function | `Type::new()` associated fn |46| Builder pattern | `__init__` + kwargs / dataclass | Fluent builder class | Functional options | Builder with consuming `self` |4748For detailed concept-to-language mappings, see `references/language-idioms.md`.4950## Core Philosophy5152**Refactoring is the process of changing the internal structure of code without altering its observable behavior.** It is a disciplined technique, not a random cleanup. The golden rule is: Cover → Modify → Refactor (always have tests before you start).5354## How to Use This Skill55561. **Detect** the language (Step 0 above)572. **Diagnose first**: Identify the code smell (see `techniques/00-code-smells-diagnostic.md`)583. **Check applicability**: See `references/language-applicability.md` for technique availability per language594. **Select technique**: Each smell maps to one or more refactoring techniques; when several compete, use `references/selection-heuristics.md` for the ordered decision rules605. **Read the technique file**: Each technique has multi-language examples (Python, TypeScript, Go, Rust)616. **For Java**: Read `references/java-notes.md`, use Java OOP/Stream idioms, honor Java 8 versus Java 11+ API availability, and finish with the Java completion gate627. **For language idiom mapping**: See `references/language-idioms.md`638. **Apply incrementally**: Small steps, test after each change, commit frequently6465## Technique Categories6667The techniques are organized in 7 groups. Each technique has its own file in the `techniques/` directory.6869### Group 1: Composing Methods (techniques/01-XX)70Techniques for building clean, well-structured methods. The foundation of all refactoring.71- `01-extract-method.md` — Extract a code fragment into a named function72- `02-inline-method.md` — Replace a function call with the function body73- `03-extract-variable.md` — Give a name to a complex expression74- `04-inline-variable.md` — Remove a variable that adds no clarity75- `05-replace-temp-with-query.md` — Replace temp variables with function calls76- `06-replace-method-with-method-object.md` — Turn a complex function into its own class/struct77- `07-substitute-algorithm.md` — Replace an algorithm with a clearer version7879### Group 2: Moving Features (techniques/02-XX)80Techniques for placing code where it truly belongs.81- `08-move-method.md` — Move a function to where it has more cohesion82- `09-move-field.md` — Move a field to the type that uses it most83- `10-extract-class.md` — Split a type with multiple responsibilities84- `11-inline-class.md` — Merge a type that does too little85- `12-hide-delegate.md` — Encapsulate chain navigation behind a simpler interface86- `13-remove-middle-man.md` — Remove unnecessary delegation87- `14-move-statements.md` — Move statements into/out of functions, slide statements88- `15-split-loop.md` — Separate a loop that does multiple things89- `16-replace-loop-with-pipeline.md` — Use declarative pipelines instead of imperative loops90- `17-remove-dead-code.md` — Delete unused code9192### Group 3: Organizing Data (techniques/03-XX)93Techniques for enriching data with behavior and protecting internal state.94- `18-encapsulate-variable.md` — Wrap data access with getters/functions95- `19-encapsulate-record.md` — Convert data structures into objects/structs96- `20-encapsulate-collection.md` — Protect collections from external mutation97- `21-replace-primitive-with-object.md` — Create domain types instead of using raw primitives98- `22-split-variable.md` — Give each purpose its own variable99- `23-rename-field.md` — Improve field names for clarity100- `24-replace-derived-variable-with-query.md` — Calculate values on demand101- `25-change-reference-to-value.md` — Make objects immutable (Value Objects)102- `26-change-value-to-reference.md` — Share a single instance across consumers103- `27-replace-type-code-with-subclasses.md` — Convert type codes to polymorphic hierarchy104105### Group 4: Simplifying Conditionals (techniques/04-XX)106Techniques for taming conditional complexity.107- `28-decompose-conditional.md` — Name condition and branches108- `29-consolidate-conditional.md` — Merge related conditions109- `30-replace-nested-conditional-with-guard-clauses.md` — Early returns for special cases110- `31-replace-conditional-with-polymorphism.md` — Use polymorphism instead of switch/if-type111- `32-introduce-special-case.md` — Null Object pattern for default behavior112- `33-introduce-assertion.md` — Document invariants with executable assertions113- `34-replace-control-flag.md` — Replace boolean flags with break/return114115### Group 5: Simplifying Method Calls / API Design (techniques/05-XX)116Techniques for building self-documenting interfaces.117- `35-change-function-declaration.md` — Rename functions and change parameters118- `36-introduce-parameter-object.md` — Group related parameters into an object119- `37-parameterize-function.md` — Unify similar functions with a parameter120- `38-remove-flag-argument.md` — Replace boolean params with named functions121- `39-preserve-whole-object.md` — Pass the object instead of extracted values122- `40-replace-parameter-with-query.md` — Let the function calculate what it needs123- `41-replace-query-with-parameter.md` — Pass value as param for purity/testability124- `42-remove-setting-method.md` — Make properties read-only125- `43-replace-constructor-with-factory.md` — Use factory functions for flexible creation126- `44-replace-function-with-command.md` — Encapsulate function as object127- `45-separate-query-from-modifier.md` — CQS: separate reads from writes128129### Group 6: Dealing with Generalization (techniques/06-XX)130Techniques for refactoring type hierarchies and shared behavior.131- `46-pull-up-method.md` — Move duplicated functions to shared parent/trait/interface132- `47-push-down-method.md` — Move specialized functions to specific types133- `48-pull-up-constructor-body.md` — Unify constructor/initialization logic134- `49-extract-superclass.md` — Create common parent for shared behavior135- `50-extract-interface.md` — Define a contract without implementation136- `51-collapse-hierarchy.md` — Merge unnecessary hierarchy levels137- `52-form-template-method.md` — Template Method pattern138- `53-replace-subclass-with-delegate.md` — Composition over inheritance139- `54-replace-superclass-with-delegate.md` — Replace extends with has-a140- `55-replace-inheritance-with-delegation.md` — General inheritance to delegation141142### Group 7: Additional Techniques (techniques/07-XX)143Cross-cutting techniques from both sources.144- `56-combine-functions-into-class.md` — Group functions that share data145- `57-combine-functions-into-transform.md` — Enrich read-only data146- `58-split-phase.md` — Separate code into processing phases147- `59-introduce-foreign-method.md` — Extend third-party types you can't modify148- `60-introduce-local-extension.md` — Wrapper or subclass for library extension149- `61-replace-error-code-with-exception.md` — Modernize error handling150- `62-replace-exception-with-test.md` — Don't use exceptions for control flow151152## Diagnostic Guide153154Start with `techniques/00-code-smells-diagnostic.md` to identify which techniques apply to your code. The diagnostic maps 24 code smells to their recommended refactoring techniques.155156## Applying the Skill157158When given code to refactor:1591601. Detect the language (Step 0)1612. Read `techniques/00-code-smells-diagnostic.md` to identify the smells present1623. For each identified smell, read the corresponding technique file(s)1634. Check `references/language-applicability.md` — if the technique doesn't apply to the target language, the table shows the alternative1645. Apply techniques in small steps, always testing between changes1656. Provide idiomatic examples for the detected language1667. Explain WHY each refactoring improves the code, not just HOW to do it1678. For Java, report the `references/java-notes.md` Java completion gate verdict1689. For language-specific idiom translations, consult `references/language-idioms.md`169170## Key Principles171172These principles underpin every technique in the catalog:1731741. **Names matter more than length** — a well-named 1-line function is better than an inline expression1752. **Small steps** — extract small fragments, test, commit. Never batch multiple changes1763. **Intention over implementation** — code should communicate WHAT, not HOW1774. **Data and logic that change together should live together** — cohesion is king1785. **Prefer composition over inheritance** — delegation is more flexible than extends1796. **Immutability is a powerful preservative** — immutable data is easier to reason about1807. **CQS (Command-Query Separation)** — a function either returns a value or modifies state, never both181182## Reference Files183184| File | Content |185|---|---|186| `references/language-idioms.md` | Refactoring concept → {Python, TypeScript, Go, Rust} equivalents |187| `references/language-applicability.md` | 62-technique × language applicability matrix with alternatives |188| `references/java-notes.md` | Java-specific constraints, Java 8 vs 11+ notes, and the Java completion gate |189| `references/selection-heuristics.md` | Ordered decision rules when several techniques compete: conditionals tree, smell directionality, falsifiable micro-tests, inheritance→delegation triggers |190| `references/technique-to-pattern.md` | Which refactoring techniques land on which GoF pattern (Kerievsky bridge) |