Use when adding new error messages to React, or seeing "unknown error code" warnings.
npx skills add emvnuel/SKILL.md --skill "refactoring-catalog"
Install specific skill from multi-skill repository
# Description
Identifies code smells and applies refactoring techniques from Martin Fowler's catalog. Use when improving code structure, reducing complexity, or eliminating smells without changing behavior.
# SKILL.md
name: refactoring-catalog
description: Identifies code smells and applies refactoring techniques from Martin Fowler's catalog. Use when improving code structure, reducing complexity, or eliminating smells without changing behavior.
Refactoring Catalog
Systematic techniques for improving code structure without changing its observable behavior. Based on Martin Fowler's Refactoring Catalog.
Composing Methods
Extract Function
Smell: Long method, code fragment that can be grouped
Action: Turn the fragment into a method with a name explaining its purpose
Cookbook: extract-function.md
Inline Function
Smell: Function body is as clear as its name
Action: Replace calls with the function body and remove the function
Cookbook: inline-function.md
Extract Variable
Smell: Complex expression that's hard to understand
Action: Place the result in a temporary variable with a meaningful name
Cookbook: extract-variable.md
Inline Variable
Smell: Variable name doesn't communicate more than the expression
Action: Replace references with the expression itself
Cookbook: inline-variable.md
Replace Temp with Query
Smell: Temporary variable holding the result of an expression
Action: Extract the expression into a method and replace temp with query
Cookbook: replace-temp-with-query.md
Split Variable
Smell: Variable assigned more than once (not a loop variable)
Action: Make a separate variable for each assignment
Cookbook: split-variable.md
Moving Features
Move Function
Smell: Function references elements from another context more than its own
Action: Move it to the context it references most
Cookbook: move-function.md
Move Field
Smell: Field used more by another class than its own
Action: Move it to the class that uses it most
Cookbook: move-field.md
Move Statements into Function
Smell: Same code executed around a function call
Action: Move those statements into the function
Cookbook: move-statements-into-function.md
Move Statements to Callers
Smell: Function with behavior that some callers don't need
Action: Move the varying behavior to the callers
Cookbook: move-statements-to-callers.md
Replace Inline Code with Function Call
Smell: Inline code doing the same thing as an existing function
Action: Replace with a call to the function
Cookbook: replace-inline-code-with-function-call.md
Slide Statements
Smell: Related code fragments not next to each other
Action: Slide statements to be adjacent
Cookbook: slide-statements.md
Split Loop
Smell: Loop doing multiple things
Action: Split into separate loops for each task
Cookbook: split-loop.md
Split Phase
Smell: Code dealing with two different things
Action: Split into separate phases with intermediate data structure
Cookbook: split-phase.md
Organizing Data
Replace Primitive with Object
Smell: Primitive used to represent a domain concept
Action: Create a class with the primitive as its data
Cookbook: replace-primitive-with-object.md
Change Value to Reference
Smell: Multiple copies of the same conceptual data
Action: Replace copies with a single reference object
Cookbook: change-value-to-reference.md
Change Reference to Value
Smell: Reference object that's hard to work with
Action: Replace with a value object
Cookbook: change-reference-to-value.md
Replace Magic Literal
Smell: Literal with special meaning that's not obvious
Action: Replace with a named constant
Cookbook: replace-magic-literal.md
Rename Variable
Smell: Variable name doesn't clearly communicate its purpose
Action: Change the name to something more communicative
Cookbook: rename-variable.md
Rename Field
Smell: Field name doesn't clearly communicate its purpose
Action: Change the name to something more communicative
Cookbook: rename-field.md
Change Function Declaration
Smell: Function name/parameters don't clearly communicate purpose
Action: Rename function and/or add/remove parameters
Cookbook: change-function-declaration.md
Encapsulate Variable
Smell: Public field accessed directly
Action: Create getter/setter functions
Cookbook: encapsulate-variable.md
Encapsulate Collection
Smell: Collection returned directly, allowing modification
Action: Return a copy or read-only view
Cookbook: encapsulate-collection.md
Encapsulate Record
Smell: Record/hash used for mutable data
Action: Create a class with accessors
Cookbook: encapsulate-record.md
Simplifying Conditional Logic
Decompose Conditional
Smell: Complex conditional (if-else) with complicated conditions
Action: Extract condition and each branch into separate functions
Cookbook: decompose-conditional.md
Consolidate Conditional Expression
Smell: Multiple conditionals with the same result
Action: Combine them into a single conditional
Cookbook: consolidate-conditional-expression.md
Replace Nested Conditional with Guard Clauses
Smell: Deeply nested if-else structure
Action: Use guard clauses for special cases, return early
Cookbook: replace-nested-conditional-with-guard-clauses.md
Replace Conditional with Polymorphism
Smell: Switch/if-else selecting behavior based on type
Action: Create subclasses and override methods
Cookbook: replace-conditional-with-polymorphism.md
Introduce Special Case
Smell: Many places check for a special value (often null)
Action: Create a special case object encapsulating the behavior
Cookbook: introduce-special-case.md
Introduce Assertion
Smell: Code assumes something about program state
Action: Make the assumption explicit with an assertion
Cookbook: introduce-assertion.md
Replace Control Flag with Break
Smell: Boolean variable controlling loop exit
Action: Use break, continue, or return instead
Cookbook: replace-control-flag-with-break.md
Replace Exception with Precheck
Smell: Exception used for expected condition
Action: Check the condition first
Cookbook: replace-exception-with-precheck.md
Refactoring APIs
Separate Query from Modifier
Smell: Function that returns a value and has side effects
Action: Create two functions: one for query, one for modifier
Cookbook: separate-query-from-modifier.md
Parameterize Function
Smell: Multiple functions doing similar things with literals
Action: Combine into one function with a parameter
Cookbook: parameterize-function.md
Remove Flag Argument
Smell: Boolean argument that changes function behavior
Action: Create separate functions for each case
Cookbook: remove-flag-argument.md
Preserve Whole Object
Smell: Passing several values from one object to a function
Action: Pass the whole object instead
Cookbook: preserve-whole-object.md
Replace Parameter with Query
Smell: Parameter that can be derived from another parameter
Action: Remove the parameter and let the function calculate it
Cookbook: replace-parameter-with-query.md
Replace Query with Parameter
Smell: Function references a global or internal value directly
Action: Pass the value as a parameter
Cookbook: replace-query-with-parameter.md
Remove Setting Method
Smell: Field should be set at construction time only
Action: Remove the setter and set in constructor
Cookbook: remove-setting-method.md
Replace Constructor with Factory Function
Smell: Constructor has limitations (name, return type)
Action: Replace with a factory function
Cookbook: replace-constructor-with-factory-function.md
Replace Function with Command
Smell: Function needs to be undone, queued, or has complex state
Action: Encapsulate the function in a command object
Cookbook: replace-function-with-command.md
Replace Command with Function
Smell: Command object is too simple
Action: Replace with a plain function
Cookbook: replace-command-with-function.md
Return Modified Value
Smell: Function updates data but doesn't return it
Action: Return the modified value
Cookbook: return-modified-value.md
Replace Error Code with Exception
Smell: Function returns error code to indicate failure
Action: Throw an exception instead
Cookbook: replace-error-code-with-exception.md
Introduce Parameter Object
Smell: Group of parameters that travel together
Action: Replace them with an object
Cookbook: introduce-parameter-object.md
Dealing with Inheritance
Pull Up Method
Smell: Identical methods in sibling classes
Action: Move to the superclass
Cookbook: pull-up-method.md
Pull Up Field
Smell: Identical field in sibling classes
Action: Move to the superclass
Cookbook: pull-up-field.md
Pull Up Constructor Body
Smell: Constructors in subclasses have common code
Action: Move common code to superclass constructor
Cookbook: pull-up-constructor-body.md
Push Down Method
Smell: Method only relevant to one subclass
Action: Move it to that subclass
Cookbook: push-down-method.md
Push Down Field
Smell: Field only used by one subclass
Action: Move it to that subclass
Cookbook: push-down-field.md
Replace Type Code with Subclasses
Smell: Field/parameter that indicates type with conditional behavior
Action: Replace with subclasses
Cookbook: replace-type-code-with-subclasses.md
Remove Subclass
Smell: Subclass does too little to justify its existence
Action: Replace with a field in the superclass
Cookbook: remove-subclass.md
Extract Superclass
Smell: Multiple classes with similar features
Action: Create a superclass with the common elements
Cookbook: extract-superclass.md
Collapse Hierarchy
Smell: Subclass is no different from its superclass
Action: Merge them together
Cookbook: collapse-hierarchy.md
Replace Subclass with Delegate
Smell: Inheritance used for a single axis of variation
Action: Replace with a delegate field
Cookbook: replace-subclass-with-delegate.md
Replace Superclass with Delegate
Smell: Subclass doesn't want all of superclass behavior
Action: Replace inheritance with delegation
Cookbook: replace-superclass-with-delegate.md
Extract Class
Smell: Class doing too much, has too many responsibilities
Action: Split into two classes
Cookbook: extract-class.md
Other Refactorings
Inline Class
Smell: Class does too little to justify its existence
Action: Move all features to another class
Cookbook: inline-class.md
Hide Delegate
Smell: Client calls through one object to reach another
Action: Create a delegating method
Cookbook: hide-delegate.md
Remove Middle Man
Smell: Class has too many simple delegating methods
Action: Let clients call the delegate directly
Cookbook: remove-middle-man.md
Substitute Algorithm
Smell: Algorithm can be replaced with a clearer one
Action: Replace the body with the new algorithm
Cookbook: substitute-algorithm.md
Combine Functions into Class
Smell: Group of functions operating on the same data
Action: Form a class with the data and functions
Cookbook: combine-functions-into-class.md
Combine Functions into Transform
Smell: Reading data, computing derived values, passing around
Action: Create a transform function that enriches the data
Cookbook: combine-functions-into-transform.md
Replace Loop with Pipeline
Smell: Loop processing a collection
Action: Replace with pipeline operations (map, filter, reduce)
Cookbook: replace-loop-with-pipeline.md
Remove Dead Code
Smell: Code that's never executed
Action: Delete it
Cookbook: remove-dead-code.md
Replace Derived Variable with Query
Smell: Variable calculated from other values and stored
Action: Calculate it on demand
Cookbook: replace-derived-variable-with-query.md
Quick Reference Table
| Category | Refactoring | Primary Smell |
|---|---|---|
| Composing Methods | Extract Function | Long method, code fragment |
| Composing Methods | Inline Function | Trivial function body |
| Composing Methods | Extract Variable | Complex expression |
| Composing Methods | Inline Variable | Unnecessary variable |
| Composing Methods | Replace Temp with Query | Temp holding expression |
| Composing Methods | Split Variable | Multiple assignments |
| Moving Features | Move Function | Feature envy |
| Moving Features | Move Field | Field envy |
| Moving Features | Move Statements into Function | Repeated code around call |
| Moving Features | Move Statements to Callers | Varying behavior in function |
| Moving Features | Replace Inline Code with Function Call | Duplicate logic |
| Moving Features | Slide Statements | Separated related code |
| Moving Features | Split Loop | Loop doing multiple things |
| Moving Features | Split Phase | Mixed concerns |
| Organizing Data | Replace Primitive with Object | Primitive obsession |
| Organizing Data | Change Value to Reference | Inconsistent data |
| Organizing Data | Change Reference to Value | Complex reference handling |
| Organizing Data | Replace Magic Literal | Mysterious numbers |
| Organizing Data | Rename Variable | Unclear naming |
| Organizing Data | Rename Field | Unclear naming |
| Organizing Data | Change Function Declaration | Bad signature |
| Organizing Data | Encapsulate Variable | Public field |
| Organizing Data | Encapsulate Collection | Exposed collection |
| Organizing Data | Encapsulate Record | Naked record |
| Simplifying Conditionals | Decompose Conditional | Complex conditional |
| Simplifying Conditionals | Consolidate Conditional Expression | Duplicate conditions |
| Simplifying Conditionals | Replace Nested Conditional with Guard Clauses | Deep nesting |
| Simplifying Conditionals | Replace Conditional with Polymorphism | Type-based switching |
| Simplifying Conditionals | Introduce Special Case | Null checks |
| Simplifying Conditionals | Introduce Assertion | Hidden assumptions |
| Simplifying Conditionals | Replace Control Flag with Break | Control flag |
| Simplifying Conditionals | Replace Exception with Precheck | Exception for expected case |
| Refactoring APIs | Separate Query from Modifier | Mixed query/command |
| Refactoring APIs | Parameterize Function | Similar functions |
| Refactoring APIs | Remove Flag Argument | Boolean argument |
| Refactoring APIs | Preserve Whole Object | Data clump |
| Refactoring APIs | Replace Parameter with Query | Derivable parameter |
| Refactoring APIs | Replace Query with Parameter | Hidden dependency |
| Refactoring APIs | Remove Setting Method | Mutable after construction |
| Refactoring APIs | Replace Constructor with Factory Function | Constructor limitations |
| Refactoring APIs | Replace Function with Command | Complex function |
| Refactoring APIs | Replace Command with Function | Over-engineered command |
| Refactoring APIs | Return Modified Value | Side effect only |
| Refactoring APIs | Replace Error Code with Exception | Error code |
| Refactoring APIs | Introduce Parameter Object | Data clump |
| Dealing with Inheritance | Pull Up Method | Duplicate methods |
| Dealing with Inheritance | Pull Up Field | Duplicate fields |
| Dealing with Inheritance | Pull Up Constructor Body | Duplicate constructor code |
| Dealing with Inheritance | Push Down Method | Unused in superclass |
| Dealing with Inheritance | Push Down Field | Unused field |
| Dealing with Inheritance | Replace Type Code with Subclasses | Type code |
| Dealing with Inheritance | Remove Subclass | Trivial subclass |
| Dealing with Inheritance | Extract Superclass | Duplicate features |
| Dealing with Inheritance | Collapse Hierarchy | Identical class levels |
| Dealing with Inheritance | Replace Subclass with Delegate | Single variation axis |
| Dealing with Inheritance | Replace Superclass with Delegate | Partial inheritance |
| Dealing with Inheritance | Extract Class | Large class |
| Other | Inline Class | Lazy class |
| Other | Hide Delegate | Law of Demeter violation |
| Other | Remove Middle Man | Message chain wrapper |
| Other | Substitute Algorithm | Inferior algorithm |
| Other | Combine Functions into Class | Feature envy group |
| Other | Combine Functions into Transform | Derived data passing |
| Other | Replace Loop with Pipeline | Loop collection processing |
| Other | Remove Dead Code | Dead code |
| Other | Replace Derived Variable with Query | Stored calculation |
Cookbook Index
All 66 refactoring techniques with detailed mechanics:
Composing Methods (6): Extract Function · Inline Function · Extract Variable · Inline Variable · Replace Temp with Query · Split Variable
Moving Features (8): Move Function · Move Field · Move Statements into Function · Move Statements to Callers · Replace Inline Code with Function Call · Slide Statements · Split Loop · Split Phase
Organizing Data (10): Replace Primitive with Object · Change Value to Reference · Change Reference to Value · Replace Magic Literal · Rename Variable · Rename Field · Change Function Declaration · Encapsulate Variable · Encapsulate Collection · Encapsulate Record
Simplifying Conditional Logic (8): Decompose Conditional · Consolidate Conditional Expression · Replace Nested Conditional with Guard Clauses · Replace Conditional with Polymorphism · Introduce Special Case · Introduce Assertion · Replace Control Flag with Break · Replace Exception with Precheck
Refactoring APIs (13): Separate Query from Modifier · Parameterize Function · Remove Flag Argument · Preserve Whole Object · Replace Parameter with Query · Replace Query with Parameter · Remove Setting Method · Replace Constructor with Factory Function · Replace Function with Command · Replace Command with Function · Return Modified Value · Replace Error Code with Exception · Introduce Parameter Object
Dealing with Inheritance (12): Pull Up Method · Pull Up Field · Pull Up Constructor Body · Push Down Method · Push Down Field · Replace Type Code with Subclasses · Remove Subclass · Extract Superclass · Collapse Hierarchy · Replace Subclass with Delegate · Replace Superclass with Delegate · Extract Class
Other Refactorings (9): Inline Class · Hide Delegate · Remove Middle Man · Substitute Algorithm · Combine Functions into Class · Combine Functions into Transform · Replace Loop with Pipeline · Remove Dead Code · Replace Derived Variable with Query
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.