Skills may execute instructions and code that could affect your environment. Marketplace scans reduce risk but do not guarantee safety. Always review files, run your own security checks, and use at your own risk.
refactoring-patterns
Security Scan Summary
Status: Safe
Source: Syntic Skills registry
Automated security scan completed with no high-risk patterns detected. Manual review is still required.
About This Skill
Use when the user says 'refactor this,' mentions code smells, extract/inline method, technical debt, or wants to restructure code without changing its behavior.
Downloadable SKILL.md
Download SKILL.md and place it in your Syntic skills folder. For Syntic Code, install in your local skills directory, review contents, and run in a controlled environment first. Acknowledge the risk notice above to enable the download.
--- name: refactoring-patterns description: Use when the user says 'refactor this,' mentions code smells, extract/inline method, technical debt, or wants to restructure code without changing its behavior. category: Engineering Knowledge version: 1.0.0 tools: [] --- # Refactoring Patterns Framework Improve the internal structure of existing code without changing its observable behavior. Every refactoring follows the same loop: verify tests pass, apply one small structural change, verify tests still pass. ## Core Principle Refactoring is not rewriting — it is a sequence of small, behavior-preserving transformations, each backed by tests. Never change what the code does, only how it is organized. Big-bang rewrites fail because they combine structural change with behavioral change, making it impossible to know what broke. Bad code is a natural consequence of delivering under time pressure, not a character flaw. Code smells are objective signals of degraded structure: the smell catalog says *where* to look, the refactoring catalog says *what to do*. ## Scoring Score structural quality 0-10 by how many of the eight Quick Diagnostic checks pass: `score = round(passed / 8 × 10)`, adjusted down when a single smell is severe. - **9-10**: no obvious smells, each function does one thing, names reveal intent, duplication eliminated, conditionals use polymorphism where apt, tests cover refactored paths - **5-6**: a few smells remain (a Long Method, some duplication) but structure is mostly sound - **≤3**: pervasive smells — tangled conditionals, God classes, duplication everywhere — or no tests to refactor safely Always state the current score, name the smells driving it down, and list the specific refactorings needed to reach 10/10. ## The Refactoring Patterns Framework Six areas of focus: ### 1. Code Smells as Triggers Code smells are surface indicators of deeper structural problems — signals the design makes code harder to understand, extend, or maintain. Named smells give teams objective criteria instead of "I don't like this": "This is Feature Envy" points straight at the fix. Smells cluster into five families: Bloaters, Object-Orientation Abusers, Change Preventers, Dispensables, Couplers. Long Method is the most common smell; Duplicate Code is the most expensive. A method needing a comment to explain *what* it does is a smell — extract and name the block instead. Shotgun Surgery (one change, many classes) and Divergent Change (one class, many reasons to change) are opposite signals of misplaced responsibility. Primitive Obsession — raw strings/ints instead of small domain objects — spreads errors and duplication. | Context | Pattern | Example | |---------|---------|---------| | Method > 10 lines | Extract Method | Pull loop body into `calculateLineTotal()` | | One change touches many classes | Move Method/Field | Gather scattered behavior into one class | | Same params in many methods | Introduce Parameter Object | `startDate, endDate` → `DateRange` | | Copy-pasted logic | Extract Method + Pull Up Method | Share via common method or base class | ### 2. Composing Methods Most refactoring starts here: break long methods into smaller, well-named pieces that read like prose. Extract Method is the single most important refactoring — master it first. Urge to write a comment? Extract the block and use the comment as the method name. Inline Method when the body is as clear as the name — indirection without value is noise. Replace Temp with Query for computed values used in multiple places; Split Temporary Variable when one temp serves two purposes. Replace Method with Method Object when locals are too tangled to extract — they become fields on a new class. | Context | Pattern | Example | |---------|---------|---------| | Block with a comment | Extract Method | `// check eligibility` → `isEligible()` | | Temp used once | Inline Variable | Drop `const price = order.getPrice()` | | Trivial delegating method | Inline Method | Inline `return deliveries > 5` if used once | | Tangled locals | Replace Method with Method Object | Locals become fields in a new class | ### 3. Moving Features Between Objects The key OO design decision is where responsibilities live. When Feature Envy, excessive coupling, or unbalanced class sizes show a method or field is in the wrong class, move it. A method placed away from the data it uses creates invisible cross-class dependencies — one logical change ripples across many files (Shotgun Surgery). Co-locating method and data confines the change to one class. Move Method when a method uses more of another class's features than its own; Move Field likewise. Extract Class when one class does two things; Inline Class when one does too little. Hide Delegate enforces the Law of Demeter; Remove Middle Man undoes it when forwarding becomes the whole class — hide the delegate when the chain is unstable, remove the middle man when it's pure forwarding. | Context | Pattern | Example | |---------|---------|---------| | Method envies another class | Move Method | `calculateShipping()` from `Order` to `ShippingPolicy` | | God class 500+ lines | Extract Class | Pull `Address` fields/methods into own class | | `a.getB().getC()` chains | Hide Delegate | Add `a.getCThroughB()` | | Class only forwards calls | Remove Middle Man | Let client call the delegate directly | ### 4. Organizing Data Raw data — magic numbers, exposed fields, integer type codes — creates subtle bugs and scatters domain knowledge. Replace primitives with objects that encapsulate behavior and enforce invariants: an `int` amount has no rounding rules or currency code, a `Money` object encapsulates all of it. Replace Magic Number with Symbolic Constant is the simplest data refactoring. Replace Data Value with Object cures Primitive Obsession (`EmailAddress`, `Money`, `Temperature`). Encapsulate Field and Encapsulate Collection — never expose raw fields or mutable internal lists. Replace Type Code with Subclasses when the code affects behavior, with Strategy when subclassing is impractical. Change Value to Reference when you need identity semantics. | Context | Pattern | Example | |---------|---------|---------| | `if (status == 2)` | Replace Magic Number | `if (status == ORDER_SHIPPED)` | | `String email` everywhere | Replace Data Value with Object | `EmailAddress` class with validation | | Getter returns mutable list | Encapsulate Collection | `Collections.unmodifiableList(items)` | | `int typeCode` with switch | Replace Type Code with Subclasses | `Employee` → `Engineer`, `Manager` | ### 5. Simplifying Conditional Logic Deeply nested if/else trees, long switches, and scattered null checks are the hardest code to read and most bug-prone. Decompose Conditional extracts the condition, then-branch, and else-branch into named methods. Consolidate Conditional Expression merges conditions with the same result. Replace Nested Conditional with Guard Clauses handles edge cases early and returns, keeping the main path unindented. Replace Conditional with Polymorphism is the gold standard for type-based conditionals. Introduce Special Case (Null Object) eliminates scattered `if (x == null)` checks; Introduce Assertion makes assumptions fail fast. | Context | Pattern | Example | |---------|---------|---------| | Long `if` with complex condition | Decompose Conditional | Extract `isSummer(date)` and `summerCharge()` | | Deeply nested `if/else` | Guard Clauses | Edge cases first, return early, flat main path | | Switch on object type | Replace Conditional with Polymorphism | Each type implements its own `calculatePay()` | | `if (customer == null)` everywhere | Introduce Special Case | `NullCustomer` with safe default behavior | ### 6. Safe Refactoring Workflow Refactoring is only safe when wrapped in tests: run tests (green), apply one small transformation, run tests (green), commit. If tests go red, revert — don't debug a broken refactoring; small steps make the failure obvious and reverting costs seconds, while debugging a failed big-bang rewrite costs days. Rule of Three: tolerate duplication once, note it twice, refactor on the third occurrence. Preparatory refactoring restructures to make a feature easy to add *before* adding it. Skip refactoring when rewriting is easier, no tests exist and adding them isn't feasible, or the code will be deleted soon. Refactor for clarity first, then profile and optimize the measured bottleneck. Branch by Abstraction and Parallel Change enable large refactorings in production without long-lived branches. | Context | Pattern | Example | |---------|---------|---------| | About to add a feature | Preparatory Refactoring | Clean the insertion point first | | Third copy of same logic | Rule of Three | Extract shared logic now | | Large API change in production | Branch by Abstraction | Add abstraction layer, migrate callers, remove old path | | Renaming a widely-used method | Parallel Change | Add new, deprecate old, migrate, remove | ## Common Mistakes | Mistake | Why It Fails | Fix | |---------|-------------|-----| | Refactoring without tests | No safety net to detect behavior change | Write characterization tests first | | Big-bang rewrite | Mixes structural and behavioral change; undebuggable | Smallest possible steps, tests after each | | Refactoring while adding features | Two hats at once — neither change verifiable | Refactor first (commit), then add feature (commit) | | Renaming without updating callers | Broken build or dead code | Search all references before renaming | | Extracting too many tiny methods | Indirection without clarity when names are poor | Each name must remove the need to read the body | | Ignoring the smell catalog | Reinvents fixes instead of applying proven recipes | Learn named smells; each maps to refactorings | | Refactoring doomed code | Polish on condemned code is waste | Check the code's lifespan justifies the investment | | Optimizing while refactoring | Conflates clarity with performance | Clarity first, then profile, then optimize hot path | ## Quick Diagnostic | Question | If No | Action | |----------|-------|--------| | Do tests pass before you start? | No safety net | Write or fix tests first — never refactor red | | Can you name the smell you're fixing? | Refactoring by instinct, not catalog | Identify the smell, apply its prescribed refactoring | | Is each method under ~10 lines? | Long Method likely | Extract Method into named steps | | Does each class have one reason to change? | Divergent Change or Large Class | Extract Class to separate responsibilities | | Are there duplicated code blocks? | The most expensive smell | Extract shared logic into common method/base class | | Do conditionals use polymorphism where apt? | Switch Statements remain | Replace Conditional with Polymorphism | | Are you committing after each step? | Risk losing work, mixing changes | Commit after every green-to-green transformation |
Bundle Download
Includes SKILL.md and bundled support files where provided. Risk acknowledgement is required.
Install Targets
Syntic App
- 1. Create a dedicated folder for this skill in your local skills library.
- 2. Place SKILL.md into that folder.
- 3. Restart Syntic and invoke this skill on matching tasks.
Syntic Code (CLI)
- 1. Save SKILL.md in your local Syntic Code skills directory.
- 2. Keep related files in the same skill folder.
- 3. Run in a safe environment and validate outputs.
Source
https://github.com/wondelai/skills/blob/main/refactoring-patterns/SKILL.md
Open Source LinkRelated Skills
clean-architecture
Use when discussing architecture layers, the dependency rule, hexagonal/onion/screaming architecture, where...
Engineering Knowledgeclean-code
Use when cleaning up code, a function is too long, code smells, naming conventions, single responsibility...
Engineering Knowledgeddia-systems
Use when choosing a database, weighing SQL vs NoSQL, diagnosing replication lag or a partitioning strategy...
Engineering Knowledgehigh-perf-browser
Use when a site is slow, diagnosing Core Web Vitals, HTTP/2 or HTTP/3, resource hints, render-blocking...