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