Module 2: Refactoring Techniques
Primary text: Refactoring: Improving the Design of Existing Code (Fowler, 2nd edition) Selective support: Working Effectively with Legacy Code ideas (seams, enabling points), Clean Code for readability pressure, Good Code, Bad Code for engineering judgment around rollout
This guide is the primary teacher. You do not need to read Fowler's catalog front-to-back to complete this module. You do need to become operational at naming a refactor move, executing it in small behavior-preserving steps, collecting behavioral evidence and stating its limits, and knowing when to stop.
Scope of This Module
This module is not a pattern-name trivia quiz. It is where "clean up the code" stops being vague and becomes a named, disciplined sequence of moves under a test harness.
What it covers in depth:
- the precise definition of refactoring as behavior preservation
- the two-hats discipline that distinguishes structural changes from intentional repairs
- useful triggers: rule of three, preparatory, comprehension, and opportunistic
- characterization tests that pin current behavior before any structural change
- seams and enabling points from Working Effectively with Legacy Code
- the core Fowler moves: Extract/Inline Function, Extract Variable, Rename, Change Function Declaration, Move Function/Field, Split Phase, Encapsulate Record, Replace Primitive with Object
- conditional restructuring: Replace Conditional with Polymorphism, Decompose Conditional, Consolidate Conditional Expression
- API reshaping: Introduce Parameter Object, Preserve Whole Object
- large-scale strategies: Branch by Abstraction, Parallel Change, Strangler Fig
What it deliberately does not try to finish here:
- the full Fowler catalog of seventy-plus refactorings
- comprehensive legacy-code recovery techniques (Module 5 and future)
- design patterns as destinations (that is Modules 3 and 4)
- team-process choreography like feature branching and trunk-based development (Track B)
This is the operational core. If you can quote the names but cannot execute the moves without breaking tests, you are not done.
Before You Start
Use the prerequisite diagnostic for tracing, exceptions, iterators and Module 1 contracts. The refactoring moves are outcomes here, not entry tests.
What This Module Is For
Refactoring is a discipline for restructuring under explicit preservation obligations. Every real codebase asks questions like:
- how do I clean up this 300-line function without breaking the existing callers?
- how do I add a new feature when the shape of the existing code fights me?
- how do I get this untested legacy class under test before I change it?
- how do I replace a library dependency without a six-month branch?
- which of the ten code smells I just spotted should I fix first?
This module builds the change-safety skills needed for:
- Module 3 and 4, where patterns are often introduced by refactoring, not written from scratch
- Module 5, where code review depends on being able to read diffs move by move
- real production work, where replacement strategy depends on compatibility, state, migration cost and recovery constraints
You are learning to reshape running code without stopping it.
Concept Map
How To Use This Module
Work in order. Later clusters assume the discipline and test habits from earlier ones.
Cluster 1: The Refactoring Discipline
| Order | Concept | Type | Focus |
|---|---|---|---|
| 1 | Refactoring Is Behavior Preservation | PRIMARY | Fowler's precise definition and why "any cleanup" is not refactoring |
| 2 | The Two Hats: Separate Structural and Behavior Changes | PRIMARY | Separate intentions and reviewable evidence |
| 3 | When to Refactor: Rule of Three, Preparatory, Opportunistic, Comprehension | PRIMARY | Triggers, bounded benefit and justified dedicated migrations |
Cluster mastery check: Can you separate structural work from intended behavior changes and explain what bisect can locate?
Cluster 2: Tests as a Safety Net
| Order | Concept | Type | Focus |
|---|---|---|---|
| 4 | Characterization Tests: Pin Behavior Before Change | PRIMARY | Capturing current behavior, including bugs, as the baseline |
| 5 | Legacy Seams and Enabling Points | PRIMARY | Feathers' vocabulary for breaking dependencies without editing everywhere |
| 6 | Test Granularity: Unit vs Integration During a Refactor | SUPPORTING | Which level of test actually protects which kind of move |
Cluster mastery check: Can you name a seam in code you wrote this week and the enabling point that would activate a stub?
Cluster 3: Fundamental Refactor Moves
| Order | Concept | Type | Focus |
|---|---|---|---|
| 7 | Extract Function and Inline Function | PRIMARY | The intention/implementation split and its inverse |
| 8 | Extract Variable, Rename, Change Function Declaration | PRIMARY | Naming as a refactor discipline, not a cosmetic |
| 9 | Move Function, Move Field, Split Phase | PRIMARY | Relocation moves that fix coupling and sequential-phase tangles |
| 10 | Encapsulate Record and Replace Primitive with Object | PRIMARY | Giving anonymous data a home and behavior |
Cluster mastery check: Can you extract a useful calculation while preserving output, failures and evaluation order?
Cluster 4: Reorganizing Data and Logic
| Order | Concept | Type | Focus |
|---|---|---|---|
| 11 | Replace Conditional with Polymorphism | PRIMARY | Turning recurring switch statements into type-dispatched behavior |
| 12 | Introduce Parameter Object and Preserve Whole Object | SUPPORTING | Shrinking parameter lists by letting data clumps become types |
| 13 | Decompose and Consolidate Conditional | SUPPORTING | Extracting the "why" from tangled branches; combining parallel branches |
Cluster mastery check: Can you decide between polymorphism, parameter object, and a decomposed conditional for a given smelly function, and justify the choice?
Cluster 5: Refactoring Large Changes and Rollout
| Order | Concept | Type | Focus |
|---|---|---|---|
| 14 | Branch by Abstraction and Parallel Change | PRIMARY | Keeping the system shippable through a multi-week change |
| 15 | Incremental Strangler Refactors in Production | SUPPORTING | Replacing a legacy component while users are still using it |
Cluster mastery check: Can you sketch how to replace a hand-rolled ORM with a library in a system shipped three times a week, without a two-month branch?
Cluster 6: Evidence and Migration Contracts
- Evaluation Order, Aliases, and Observation Boundaries
- Differential Oracles and Mutation Evidence
- Migration State Authority and Uncertain Writes
Mastery check: Can you defend the observation boundary, challenge an oracle and explain why routing rollback may not recover state?
Then work these practice pages:
| Order | Practice path | Focus |
|---|---|---|
| 1 | Behavior Preservation Lab | Characterization tests and seam identification |
| 2 | Small Refactor Moves Workshop | Extract, inline, rename, move drills with tests green |
| 3 | Conditional and Data Restructuring Clinic | Polymorphism, parameter objects, decomposed conditionals |
| 4 | Code Katas | Mixed-client migration and changed-contract tasks |
Use Module Quiz after the concept and practice path. Use Reference and Selective Reading and Learning Resources only for targeted reinforcement.
Learning Objectives
By the end of this module you should be able to:
- State Fowler's definition of refactoring and explain what "observable behavior" rules in and out.
- Separate structural and intentional behavior changes in reviewable evidence, using coherent checkpoints.
- Choose between rule-of-three, preparatory, opportunistic, and comprehension refactoring as triggers.
- Write characterization tests for a function whose current behavior is not documented.
- Identify seams in legacy code and name the enabling point for each seam.
- Execute Extract Function, Inline Function, Extract Variable, Rename, and Change Function Declaration without breaking tests.
- Execute Move Function, Move Field, and Split Phase on code where the module boundary was wrong.
- Execute Encapsulate Record and Replace Primitive with Object to give data a home.
- Replace a recurring type-switch with polymorphism, and know when not to.
- Introduce Parameter Object, Preserve Whole Object, Decompose Conditional, and Consolidate Conditional Expression deliberately.
- Plan a large-scale change using Branch by Abstraction, Parallel Change, or a Strangler Fig, keeping the system shippable throughout.
- Preserve evaluation count, order, iterator semantics and failure precedence during a transformation.
- Combine differential comparison with independent oracles and explain what deliberately seeded faults test.
- Define mixed-client state authority and distinguish traffic rollback from recovery of uncertain writes.
Outputs and Completion
Keep P01–P20 attempts, five runnable lab transformations, three experiments, ten independent assessment answers and the bounded project. Reuse valid evidence; do not manufacture mistakes, refactors, seams or commits to satisfy quotas. The untouched starter already passes; checked intermediate diffs and a defense are essential process evidence.
Meet every C01–C10 gate in the assessment map, reproduce the labs, and defend a changed case after 7–14 days. Keep self-assessment and independent review distinct. This authored candidate awaits human review and learner pilots.
Reading Policy
- Concept pages are the main path.
- The Refactoring book chunks are selective reinforcement, not a second syllabus.
Read only if stuckmeans try the concept page, self-check, and drill first.Optional deep divemeans additional nuance or alternate examples, not required progression.- External Fowler articles are cited only where they add something the book chunks do not already carry.
Suggested Workload and Sequence
Plan 90–130 focused hours, an author estimate awaiting learner pilots.
| Phase | Hours |
|---|---|
| Diagnostic, 18 lessons and selective reading | 26–36 |
| Twenty practice tasks | 16–22 |
| Five runnable labs | 20–30 |
| Three experiments | 6–10 |
| Assessment, repair and delayed recheck | 6–10 |
| Project and defense | 16–22 |
At ten hours weekly this is about 9–13 study weeks. Prerequisite repair, optional reading and unabsorbed retention delays add time. The former seven-day schedule is retired. Interleave practice and labs with the concept clusters; use the contracts before editing the starter.
Reference
If you need exact links into the local chunked books, use Reference and Selective Reading.
Rich Learning Pages
Worked Examples | Guided Labs | Case Studies | Mistake Clinic | Reading Guide | Capstone Thread
Model Artifact Calibration
For reviewable refactoring evidence, compare your writeup to the refactor PR model artifact.