smallnest/goal-workflow/refactor

Trust tier 2
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Expert code refactoring based on Martin Fowler's catalog — improve maintainability without changing behavior. Covers code smells, composing methods, moving features, organizing data, simplifying conditionals, method calls, and generalization. Triggers on: refactor, 重构, clean up, improve code, code smell, extract method, rename, simplify.

Install

npx vskill@latest install smallnest/goal-workflow/refactor

SKILL.md

Refactor — Expert Code Restructuring

Surgical code refactoring based on Martin Fowler's <Refactoring> (2nd Edition) catalog. Improve structure, readability, and maintainability without changing external behavior. Gradual evolution, not revolution.


When to Use

This skill activates when:

  • Code is hard to understand or maintain
  • Functions/classes have grown too large
  • Code smells are detected
  • Adding features is difficult due to poor structure
  • User explicitly requests refactoring, cleanup, or improvement
  • User says: refactor, 重构, clean up, improve code, code smell, extract method, rename, simplify

The Golden Rules

These five rules are non-negotiable. Violating any of them turns refactoring into reckless editing.

1. Behavior is Preserved

Only how the code works changes, never what it does. If tests existed before, they must pass after. If the refactoring introduces a behavioral change, it's not refactoring — it's rewriting.

2. Small Steps

Each change should be the smallest possible transformation that compiles and passes tests. If a step breaks, you know exactly which change caused it. Refactoring is a series of tiny, safe transformations, not one big rewrite.

3. Version Control is Your Friend

Commit before starting. Commit after each successful step. This gives you infinite undo. Branch from a clean state so you can abandon the refactoring without consequences.

4. Tests are Essential

"Without tests, you're not refactoring — you're just editing." If tests don't exist for the target code, write characterization tests first. These tests capture the current behavior so you can detect regressions.

5. One Thing at a Time

Never mix refactoring with feature changes. Never refactor two unrelated things simultaneously. Each commit should contain exactly one refactoring operation.


When NOT to Refactor

ScenarioAction
Code works and won't change againLeave it alone
Critical production path with no testsWrite characterization tests first
Under tight deadline pressureDocument the smell, refactor later
No clear purpose or benefitDon't refactor for refactoring's sake
Code is fundamentally wrongThis is a rewrite, not a refactoring

Refactoring Decision Rubric

Principles guide judgment; they are not independent reasons to rewrite code. Before choosing a Fowler technique, record one decision card:

FieldRequired answer
Primary smellOne root cause, not one entry per principle
EvidenceLocation, behavior, callers, change history, or measurement
Primary principleThe most specific applicable principle
Related principlesExplanatory labels only; do not count separately
Expected impactObservable reduction in change spread, cognitive load, duplicated knowledge, coupling, delayed failure, or measured runtime cost
Smallest refactoringThe least invasive Fowler technique that addresses the root cause
Baseline / success conditionHow behavior preservation and the expected benefit will be verified

Use these four decision lenses:

LensPrinciplesQuestions to answer
Responsibility and dependenciesSOLID, SRP, OCP, DIP, Separation of ConcernsAre reasons to change mixed? Does a real new variant repeatedly modify stable logic? Does high-level policy depend on concrete mechanism? Do concerns leak across a boundary?
Reuse and structureDRY, CompositionIs the same knowledge duplicated, or merely similar syntax? Would composition localize a real variation better than inheritance?
Simplicity and scopeKISS, YAGNIIs the proposed structure simpler for today's problem? Is every abstraction backed by an existing variation or boundary?
Runtime and feedbackFail Fast, Measure FirstCan invalid state fail nearer its source without changing error semantics? What baseline proves the problem and the result?

SOLID is an umbrella. When evidence supports SRP, OCP, or DIP, use that specific lens and do not create a second SOLID issue. LSP and ISP may be labeled SOLID/LSP and SOLID/ISP. DRY means shared knowledge, not all similar code. Composition is preferred when inheritance creates real coupling, not by default. OCP and DIP never justify speculative layers that violate KISS or YAGNI.

Numeric thresholds in this skill—line counts, parameter counts, method counts, and nesting depth—are context-dependent candidate indicators. Confirm mixed responsibilities, cognitive cost, repeated change, duplicated knowledge, or measured runtime impact before acting.


Code Smells Catalog

Based on Fowler's taxonomy. Before refactoring, identify which smell is present.

Bloaters
SmellDescriptionPrimary Refactoring
Long MethodCandidate: method > 10-15 lines; confirm mixed responsibilities or cognitive costExtract Method, Replace Temp with Query
Large ClassCandidate: many fields/methods; confirm independent reasons to changeExtract Class, Extract Subclass
Primitive ObsessionUsing primitives instead of small objectsReplace Data Value with Object, Replace Type Code with Class
Long Parameter ListCandidate: > 3-4 parameters; confirm a missing concept or recurring data clumpIntroduce Parameter Object, Preserve Whole Object
Data ClumpsSame group of data appearing togetherExtract Class, Introduce Parameter Object
Object-Orientation Abusers
SmellDescriptionPrimary Refactoring
Switch StatementsRepeated switch/if-else on type codesReplace Conditional with Polymorphism, Replace Type Code with Subclasses
Temporary FieldField only set in certain circumstancesExtract Class, Introduce Null Object
Refused BequestSubclass doesn't use inherited membersReplace Inheritance with Delegation, Push Down Method/Field
Alternative Classes with Different InterfacesClasses doing similar things with different namesRename Method, Move Method, Extract Superclass
Change Preventers
SmellDescriptionPrimary Refactoring
Divergent ChangeOne class changed for different reasonsExtract Class
Shotgun SurgeryOne change requires many small changes across classesMove Method, Move Field, Inline Class
Parallel Inheritance HierarchiesAdding a subclass to one hierarchy forces adding to anotherMove Method, Move Field
Dispensables
SmellDescriptionPrimary Refactoring
CommentsComments explaining what code does (not why)Extract Method, Rename Variable, Introduce Assertion
Duplicate CodeSame code structure in multiple placesExtract Method, Pull Up Method, Form Template Method
Lazy ClassClass doing too little to justify existenceInline Class, Collapse Hierarchy
Data ClassClass with only fields and getters/settersMove Method, Encapsulate Field, Encapsulate Collection
Dead CodeUnused code, imports, commented-out blocksDelete it (git history has it)
Speculative GeneralityCode built for "someday" that never cameInline Class, Collapse Hierarchy, Remove Parameter
Couplers
SmellDescriptionPrimary Refactoring
Feature EnvyMethod uses another class's data more than its ownMove Method, Extract Method + Move Method
Inappropriate IntimacyClasses know too much about each other's internalsMove Method, Move Field, Replace Delegation with Hidden Delegate
Message Chainsa.getB().getC().getD().doSomething()Hide Delegate, Extract Method
Middle ManClass delegates everything to another classRemove Middle Man, Inline Method
Incomplete Library ClassLibrary missing methods you needIntroduce Foreign Method, Introduce Local Extension

Refactoring Techniques Catalog

Organized by category, from Fowler's catalog. Each technique includes its mechanical steps.

Composing Methods
Extract Method

Turn a code fragment into a method whose name explains its purpose.

Mechanics:

  1. Create a new method named after what the fragment does (not how)
  2. Copy the extracted code into the new method
  3. Identify local variables: read-only become parameters, modified become return values
  4. Pass parameters and handle return values
  5. Replace the original fragment with a call to the new method
  6. Test

Before:

java
void printOwing() {
printBanner();
// Print details
System.out.println("name: " + _name);
System.out.println("amount: " + getOutstanding());
}

After:

java
void printOwing() {
printBanner();
printDetails(getOutstanding());
}
void printDetails(double outstanding) {
System.out.println("name: " + _name);
System.out.println("amount: " + outstanding);
}
Inline Method

Replace a method call with its body when the method body is as clear as the name.

Mechanics:

  1. Check the method is not polymorphic (no subclasses override it)
  2. Find all callers
  3. Replace each call with the method body
  4. Delete the method definition
  5. Test
Extract Variable

Put the result of an expression (or part of it) in a self-explanatory variable.

Before:

java
if (platform.toUpperCase().indexOf("MAC") > -1 &&
browser.toUpperCase().indexOf("IE") > -1 &&
wasInitialized() && resize > 0) {
// ...
}

After:

java
final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1;
final boolean wasResized = resize > 0;
if (isMacOs && isIEBrowser && wasInitialized() && wasResized) {
// ...
}
Inline Temp

Replace a temp variable with its expression when the temp is only used once and the expression is clear.

Replace Temp with Query

Extract the expression into a method. Temps that are computed once and reused are replaced with method calls.

Split Temporary Variable

A temp assigned more than once (not loop/collecting) should be split into separate variables, one per responsibility.

Remove Assignments to Parameters

Don't assign to parameters. Use a local variable instead.

Replace Method with Method Object

When a long method uses many local variables that make Extract Method hard, turn the method into its own class, with locals as fields.

Substitute Algorithm

Replace an algorithm with a clearer one.


Moving Features Between Objects
Move Method

Move a method to the class where it's used most.

Mechanics:

  1. Check all features used by the method on its current class
  2. Check for polymorphism (subclass/superclass methods)
  3. Create the method on the target class, adapting as needed
  4. Reference the target object from the source
  5. Turn the source method into a delegating method, or remove it
  6. Test
Move Field

Move a field to the class where it's used most.

Extract Class

When a class does the work of two, split it. Create a new class and move relevant fields and methods.

Inline Class

When a class does almost nothing, absorb it into the class that uses it most.

Hide Delegate

Create methods on the server to hide the delegate chain. manager = person.getDepartment().getManager() → manager = person.getManager().

Remove Middle Man

When a class is doing too much delegation, call the delegate directly.

Introduce Foreign Method

When a server class needs an additional method but you can't modify it, create a method on the client with the server instance as the first argument.

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
121
Repository forks
21
7-day trend score
24

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/smallnest/goal-workflow/refactor/badge)](https://verified-skill.com/skills/smallnest/goal-workflow/refactor)

Something wrong with this skill or its page? Tell us.