refactoring-best-practices · v1.0.0 · 2026-08-28 · sha256 16dd3e5c14920bbc
refactoring-best-practices v1.0.0A
Immutable. This exact content is served forever at /api/v1/blob/16dd3e5c14920bbc.
--- name: refactoring-best-practices description: Safe refactoring guidance for legacy and existing codebases. Use when improving design without changing behavior, creating seams around hard dependencies, migrating null/string/generic exceptions to typed failure contracts, extracting a repository from direct SQL/ORM access, introducing Domain Events into legacy workflows, adding characterization tests, splitting large classes or methods, introducing value objects, replacing conditionals, or incrementally evolving code under risk. license: MIT metadata: author: luckys version: "1.0.0" --- # Refactoring Best Practices Use this skill when the main challenge is changing existing code safely. ## Working Style 1. Protect behavior before improving design. 2. Prefer small reversible moves over dramatic rewrites. 3. Add feedback before adding abstraction. 4. Change one responsibility at a time. 5. Let the current pain point decide the next move. ## Safe Refactoring Workflow 1. Observe current behavior. - Identify outputs, side effects, and error paths. - Identify what must not change. 2. Add feedback. - Prefer characterization tests around visible behavior. - Add logs or temporary probes only when tests are not enough. 3. Find a seam. - Isolate time, file system, network, framework globals, singletons, and external APIs. - Create the narrowest possible boundary around the risky dependency. 4. Choose the next move. - extract method - extract class - introduce value object - introduce first-class collection - move method - replace conditional with polymorphism - separate construction from behavior - extract a Domain Event and one secondary subscriber 5. Re-run feedback after every meaningful step. ## High-Value Refactoring Moves - Replace a cohesive domain parameter group with a Value Object; use a Parameter Object when the group has no shared domain meaning or invariant. - Break large services into role-focused collaborators. - Move business rules out of controllers, scripts, and utility classes. - Replace type codes and unstable conditionals with explicit roles. - Wrap infrastructure behind ports or adapters. - Split classes when different method clusters change for different reasons. ## Red Flags - Big-bang rewrites. - New abstractions without a protected behavior baseline. - Splitting code into tiny classes without a clearer model. - Introducing inheritance only to make tests easier. - Refactoring based on aesthetics alone while ignoring risk. ## Decision Rules ### Refactor now when - the same knowledge is duplicated in multiple places - the code is blocking a real change - the next feature would deepen coupling or duplication - the current structure makes defects likely ### Wait when - there is no feedback loop yet - the pain is hypothetical - the abstraction is not yet stable enough to deserve a new type - the change is broad but the understanding is still weak ## References - Read `references/safe-change-workflow.md` for seam-based refactoring guidance, sensing and separation, and the legacy code change algorithm. - Read `references/refactoring-moves.md` for tactical moves, including the incremental Value Object migration sequence, and when to use them. - Read `references/code-smells.md` when recognizing a problem, using temporal co-change as design evidence, and choosing the right move. - Read `references/legacy-code-techniques.md` for Sprout, Wrap, Extract and Override, and other techniques for working without tests. - Read `references/characterization-tests.md` for how to write tests before refactoring untested code. - Read `references/domain-event-migration.md` for incrementally moving legacy side effects to events/subscribers, preserving failure semantics, durable handoff, and CDC as a migration bridge. - Read `references/error-contract-migration.md` for safely replacing nulls, strings, and generic exceptions while preserving failure timing, diagnostics, redaction, and public contracts. - Read `references/fran-iglesias-refactoring-guidance.md` for practical refactoring heuristics distilled from Fran Iglesias. - Read `references/language-examples.md` for before/after style examples in multiple languages. ## Related Skills - Use `oop-best-practices` for everyday new code decisions. - Use `design-patterns-best-practices` when the main issue is choosing an object collaboration pattern. - Use `ddd-best-practices` when moving invariants, splitting a God Aggregate, introducing a root, changing a consistency boundary, or shaping a domain Repository extracted from legacy persistence. - Use `data-migration-best-practices` for moving or backfilling persisted data; this skill owns only the safe code seams and compatibility paths around that operational migration. ## Source Influences This skill is synthesized from ideas emphasized in: - `Working Effectively with Legacy Code` by Michael Feathers - `99 Bottles of OOP` by Sandi Metz - `Practical Object-Oriented Design in Ruby` by Sandi Metz - Fran Iglesias's `Object Calisthenics` series - [CodelyTV Aggregates course](https://github.com/CodelyTV/aggregates-course) (temporal coupling and Aggregate evolution) - [CodelyTV Value Objects course](https://github.com/CodelyTV/value_objects-course) (incremental primitive-to-domain-value refactoring) - [CodelyTV Repository Pattern course](https://github.com/CodelyTV/repository_pattern-course) (incremental direct-SQL-to-port refactoring) - [CodelyTV Domain Events course](https://github.com/CodelyTV/domain_modeling-domain_events-course) (legacy event seams and CDC counterexamples) - [CodelyTV Domain Modeling Errors course](https://github.com/CodelyTV/domain_modeling-errors-course) (incremental exception-to-Result and boundary-contract lessons) - [CodelyTV Four Rules of Simple Design course](https://github.com/CodelyTV/four_rules_of_simple_design-course) (behavior-preserving tests, speculative-element deletion, and duplication counterexamples)