refactor-java
Java Refactoring Catalog Skill
A comprehensive, technique-by-technique catalog of refactoring best practices for Java, sourced from Martin Fowler's Refactoring: Improving the Design of Existing Code (2nd Edition) and Alexander Shvets' Refactoring in Java (Refactoring Guru).
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
- Diagnose first: Identify the code smell (see
techniques/00-code-smells-diagnostic.md) - Select technique: Each smell maps to one or more refactoring techniques
- Read the technique file: Each technique has its own markdown file in
techniques/with problem description, motivation, step-by-step mechanics, and Java 8 + Java 11 examples - 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 method02-inline-method.md— Replace a method call with the method body03-extract-variable.md— Give a name to a complex expression04-inline-variable.md— Remove a variable that adds no clarity05-replace-temp-with-query.md— Replace temp variables with method calls06-replace-method-with-method-object.md— Turn a complex method into its own class07-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 method to where it has more cohesion09-move-field.md— Move a field to the class that uses it most10-extract-class.md— Split a class with multiple responsibilities11-inline-class.md— Merge a class that does too little12-hide-delegate.md— Encapsulate chain navigation behind a simpler interface13-remove-middle-man.md— Remove unnecessary delegation14-move-statements.md— Move statements into/out of functions, slide statements15-split-loop.md— Separate a loop that does multiple things16-replace-loop-with-pipeline.md— Use Stream API instead of imperative loops17-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/setters19-encapsulate-record.md— Convert data structures into objects20-encapsulate-collection.md— Protect collections from external mutation21-replace-primitive-with-object.md— Create domain types instead of using raw primitives22-split-variable.md— Give each purpose its own variable23-rename-field.md— Improve field names for clarity24-replace-derived-variable-with-query.md— Calculate values on demand25-change-reference-to-value.md— Make objects immutable (Value Objects)26-change-value-to-reference.md— Share a single instance across consumers27-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 branches29-consolidate-conditional.md— Merge related conditions30-replace-nested-conditional-with-guard-clauses.md— Early returns for special cases31-replace-conditional-with-polymorphism.md— Use OOP instead of switch/if-type32-introduce-special-case.md— Null Object pattern for default behavior33-introduce-assertion.md— Document invariants with executable assertions34-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 parameters36-introduce-parameter-object.md— Group related parameters into an object37-parameterize-function.md— Unify similar functions with a parameter38-remove-flag-argument.md— Replace boolean params with named methods39-preserve-whole-object.md— Pass the object instead of extracted values40-replace-parameter-with-query.md— Let the function calculate what it needs41-replace-query-with-parameter.md— Pass value as param for purity/testability42-remove-setting-method.md— Make properties read-only43-replace-constructor-with-factory.md— Use factory methods for flexible creation44-replace-function-with-command.md— Encapsulate function as object45-separate-query-from-modifier.md— CQS: separate reads from writes
Group 6: Dealing with Inheritance (techniques/06-XX)
Techniques for refactoring class hierarchies.
46-pull-up-method.md— Move duplicated methods to superclass47-push-down-method.md— Move specialized methods to subclass48-pull-up-constructor-body.md— Unify constructor initialization49-extract-superclass.md— Create common superclass for shared behavior50-extract-interface.md— Define a contract without implementation51-collapse-hierarchy.md— Merge unnecessary hierarchy levels52-form-template-method.md— Template Method pattern from GoF53-replace-subclass-with-delegate.md— Composition over inheritance54-replace-superclass-with-delegate.md— Replace extends with has-a55-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 data57-combine-functions-into-transform.md— Enrich read-only data58-split-phase.md— Separate code into processing phases59-introduce-foreign-method.md— Extend third-party classes you can't modify60-introduce-local-extension.md— Subclass or wrapper for library extension61-replace-error-code-with-exception.md— Modernize error handling62-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 Java code to refactor:
- Read
techniques/00-code-smells-diagnostic.mdto identify the smells present - For each identified smell, read the corresponding technique file(s)
- Apply techniques in small steps, always testing between changes
- Provide both Java 8 and Java 11 versions when the language features differ meaningfully
- Explain WHY each refactoring improves the code, not just HOW to do it
Key Principles
These principles underpin every technique in the catalog:
- Names matter more than length — a well-named 1-line method 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 method either returns a value or modifies state, never both