Refactor
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.
- Skill ID
- smallnest/goal-workflow/refactor
- Publisher
- smallnest
- Repository
- goal-workflow
- Installs
- 0
- Files
- 1
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
smallnest/goal-workflow/refactorInstalls these files- SKILL.md
What this skill tells the agent
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
| Scenario | Action |
|---|---|
| Code works and won't change again | Leave it alone |
| Critical production path with no tests | Write characterization tests first |
| Under tight deadline pressure | Document the smell, refactor later |
| No clear purpose or benefit | Don't refactor for refactoring's sake |
| Code is fundamentally wrong | This 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:
| Field | Required answer |
|---|---|
| Primary smell | One root cause, not one entry per principle |
| Evidence | Location, behavior, callers, change history, or measurement |
| Primary principle | The most specific applicable principle |
| Related principles | Explanatory labels only; do not count separately |
| Expected impact | Observable reduction in change spread, cognitive load, duplicated knowledge, coupling, delayed failure, or measured runtime cost |
| Smallest refactoring | The least invasive Fowler technique that addresses the root cause |
| Baseline / success condition | How behavior preservation and the expected benefit will be verified |
Use these four decision lenses:
| Lens | Principles | Questions to answer |
|---|---|---|
| Responsibility and dependencies | SOLID, SRP, OCP, DIP, Separation of Concerns | Are 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 structure | DRY, Composition | Is the same knowledge duplicated, or merely similar syntax? Would composition localize a real variation better than inheritance? |
| Simplicity and scope | KISS, YAGNI | Is the proposed structure simpler for today's problem? Is every abstraction backed by an existing variation or boundary? |
| Runtime and feedback | Fail Fast, Measure First | Can 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
| Smell | Description | Primary Refactoring |
|---|---|---|
| Long Method | Candidate: method > 10-15 lines; confirm mixed responsibilities or cognitive cost | Extract Method, Replace Temp with Query |
| Large Class | Candidate: many fields/methods; confirm independent reasons to change | Extract Class, Extract Subclass |
| Primitive Obsession | Using primitives instead of small objects | Replace Data Value with Object, Replace Type Code with Class |
| Long Parameter List | Candidate: > 3-4 parameters; confirm a missing concept or recurring data clump | Introduce Parameter Object, Preserve Whole Object |
| Data Clumps | Same group of data appearing together | Extract Class, Introduce Parameter Object |
Object-Orientation Abusers
| Smell | Description | Primary Refactoring |
|---|---|---|
| Switch Statements | Repeated switch/if-else on type codes | Replace Conditional with Polymorphism, Replace Type Code with Subclasses |
| Temporary Field | Field only set in certain circumstances | Extract Class, Introduce Null Object |
| Refused Bequest | Subclass doesn't use inherited members | Replace Inheritance with Delegation, Push Down Method/Field |
| Alternative Classes with Different Interfaces | Classes doing similar things with different names | Rename Method, Move Method, Extract Superclass |
Change Preventers
| Smell | Description | Primary Refactoring |
|---|---|---|
| Divergent Change | One class changed for different reasons | Extract Class |
| Shotgun Surgery | One change requires many small changes across classes | Move Method, Move Field, Inline Class |
| Parallel Inheritance Hierarchies | Adding a subclass to one hierarchy forces adding to another | Move Method, Move Field |
Dispensables
| Smell | Description | Primary Refactoring |
|---|---|---|
| Comments | Comments explaining what code does (not why) | Extract Method, Rename Variable, Introduce Assertion |
| Duplicate Code | Same code structure in multiple places | Extract Method, Pull Up Method, Form Template Method |
| Lazy Class | Class doing too little to justify existence | Inline Class, Collapse Hierarchy |
| Data Class | Class with only fields and getters/setters | Move Method, Encapsulate Field, Encapsulate Collection |
| Dead Code | Unused code, imports, commented-out blocks | Delete it (git history has it) |
| Speculative Generality | Code built for "someday" that never came | Inline Class, Collapse Hierarchy, Remove Parameter |
Couplers
| Smell | Description | Primary Refactoring |
|---|---|---|
| Feature Envy | Method uses another class's data more than its own | Move Method, Extract Method + Move Method |
| Inappropriate Intimacy | Classes know too much about each other's internals | Move Method, Move Field, Replace Delegation with Hidden Delegate |
| Message Chains | a.getB().getC().getD().doSomething() | Hide Delegate, Extract Method |
More from smallnest
Use this skill in a project
Open any RiverX project, search the Skills panel for smallnest/goal-workflow/refactor, and install it in one click.
