Learning Resources
This module is populated from the local chunked books in library/raw/semester-03-software-design/books plus a small, validated set of external Fowler / Feathers resources. Use this page as a source map, not as an instruction to read everything.
Source Stack
| Book | Role | How to use it in this module |
|---|---|---|
| Refactoring: Improving the Design of Existing Code (Fowler, 2nd ed.) | Primary teaching source | Default escalation for any named refactor move, mechanics, and tradeoff reasoning |
| Working Effectively with Legacy Code (Feathers) | Selective support | Seams, enabling points, and characterization-test discipline |
| Clean Code (Martin) | Selective support | Naming and function-length pressure -- argument for why small-function style is worth the ceremony |
| Good Code, Bad Code (Hansen) | Selective support | Engineering-judgment framing for when a move pays vs. when it does not |
| Head First Design Patterns | Background only | Patterns enabled by refactoring; primary home is S3M3/S3M4 |
Resource Map by Cluster
Cluster 1: The Refactoring Discipline
| Need | Best local chunk | Why |
|---|---|---|
| precise definition of refactoring + two hats | Refactoring ch. 2 intro: Defining Refactoring and The Two Hats | Canonical definition and the hats metaphor in Fowler's own words |
| why refactor at all | Refactoring ch. 2: Why Should We Refactor? | Summary of benefits; keep this short |
| when to refactor | Refactoring ch. 2: When Should We Refactor? (Part 1) | Rule of three, preparatory, comprehension, litter-pickup |
| when to refactor -- trade-offs | Refactoring ch. 2: When Should We Refactor? (Part 2) | Planned vs opportunistic plus how to argue for refactoring to managers |
| when refactoring gets hard | Refactoring ch. 2: Problems with Refactoring (Part 1) | Slows-me-down myths and database/published-API issues |
Cluster 2: Tests as a Safety Net
| Need | Best local chunk | Why |
|---|---|---|
| why refactoring needs tests | Refactoring ch. 4: Value of Self-Testing Code | Foundational argument for self-testing |
| first test example and fixture | Refactoring ch. 4: Sample code and a first test | Concrete first-test walkthrough |
| adding tests and boundary probing | Refactoring ch. 4: Modifying the Fixture and Probing the Boundaries | Characterization-test discipline in action |
| what "enough tests" means | Refactoring ch. 4: Much More Than This | Coverage without perfection |
Cluster 3: Fundamental Refactor Moves
| Need | Best local chunk | Why |
|---|---|---|
| Extract Function mechanics | Refactoring ch. 6: Extract Function (Part 1) | Canonical motivation and simplest case |
| Extract Function with local variables | Refactoring ch. 6: Extract Function (Part 2) | How to handle captured state |
| Inline Function | Refactoring ch. 6: Inline Function | Inverse move and when indirection does not pay |
| Extract Variable | Refactoring ch. 6: Extract Variable | Local naming as intent |
| Change Function Declaration | Refactoring ch. 6: Change Function Declaration | Migration-friendly signature change |
| Rename Variable | Refactoring ch. 6: Rename Variable and Introduce Parameter Object | Scope-aware renaming |
| Move Function | Refactoring ch. 8: Move Function (Part 1) | Feature-envy remedy |
| Move Field | Refactoring ch. 8: Move Field | Data-sided feature envy |
| Split Phase | Refactoring ch. 6: Split Phase | Sequential-concerns separation |
| Encapsulate Record | Refactoring ch. 7: Encapsulate Record (Part 1) | Raw record -> class |
| Replace Primitive with Object | Refactoring ch. 7: Replace Primitive with Object | Most undervalued move per Fowler |
Cluster 4: Reorganizing Data and Logic
| Need | Best local chunk | Why |
|---|---|---|
| Decompose Conditional | Refactoring ch. 10: Decompose Conditional | Single-conditional cleanup |
| Consolidate / Guard Clauses | Refactoring ch. 10: Consolidate Conditional Expression and Replace Nested Conditional with Guard Clauses | Combining same-result guards; flattening nests |
| Replace Conditional with Polymorphism (Part 1) | Refactoring ch. 10: Replace Conditional with Polymorphism (Part 1) | Recurrence-rule and motivation |
| Replace Conditional with Polymorphism (Part 2) | Refactoring ch. 10: Replace Conditional with Polymorphism (Part 2) | Worked example with subclasses |
| Introduce Parameter Object (second half of the chunk) | Refactoring ch. 6: Rename Variable and Introduce Parameter Object | Both moves live in this chunk |
| Preserve Whole Object | Refactoring ch. 11: Preserve Whole Object | Pass the whole, not pieces |
Cluster 5: Refactoring Large Changes and Rollout
| Need | Best local chunk | Why |
|---|---|---|
| Refactoring and architecture | Refactoring ch. 2: Refactoring Architecture and YAGNI | Why structural change belongs in incremental refactoring |
| Refactoring and performance | Refactoring ch. 2: Refactoring and Performance | The "performance panic" objection answered |
| Problems with refactoring (part 3) | Refactoring ch. 2: Problems with Refactoring (Part 3) | Branches, published APIs, and long-lived migrations |
External Resources
All URLs validated on module creation; re-check before assigning.
- martinfowler.com/books/refactoring.html -- canonical book page with the precise definition
- refactoring.com/catalog/ -- full catalog of named moves with per-move cards
- refactoring.guru/refactoring -- animated second-pass explanations
- martinfowler.com/bliki/LegacySeam.html -- modern retelling of Feathers' seam vocabulary with code
- martinfowler.com/bliki/OpportunisticRefactoring.html -- camp-site rule and rabbit-hole risk
- martinfowler.com/articles/workflowsOfRefactoring/ -- infodeck on the four triggers + long-term refactoring
- martinfowler.com/articles/preparatory-refactoring-example.html -- Jessica Kerr's concrete preparatory example
- martinfowler.com/bliki/ParallelChange.html -- Danilo Sato's canonical expand / migrate / contract
- martinfowler.com/bliki/BranchByAbstraction.html -- Paul Hammant's canonical technique
- martinfowler.com/bliki/StranglerFigApplication.html -- the pattern and its metaphor
- martinfowler.com/articles/patterns-legacy-displacement/ -- catalog that generalizes Strangler
- martinfowler.com/bliki/TestPyramid.html -- test granularity
- approvaltests.com -- tooling for snapshot-style characterization tests
- github.com/emilybache/GildedRose-Refactoring-Kata -- the canonical first kata in multiple languages
Exercise Support Chunks
Use these when the concept pages are understood but your fluency is weak:
- Refactoring ch. 1 opening example (parts 1-7)
- Refactoring ch. 1: Decomposing the statement function (Part 1)
- Refactoring ch. 1: Decomposing the statement function (Part 2)
- Refactoring ch. 1: Decomposing the statement function (Part 3)
- Refactoring ch. 1: Splitting the Phases of Calculation and Formatting
- Refactoring ch. 1: Reorganizing the Calculations by Type
- Refactoring ch. 1: Creating the Data with the Polymorphic Calculator and Final Thoughts
Use Rules
- If you are unsure which move applies, read the Fowler chunk for two plausible moves and compare their motivations.
- If the concept page's mechanics are enough to execute the move, do not open the source chunk. The source is reinforcement, not a second syllabus.
- If you catch yourself reading a whole chapter end-to-end, stop. You are shifting from "learn the move" to "survey the book." They are different tasks.
- Official-looking external pages (martinfowler.com, refactoring.com, refactoring.guru) are preferred over third-party summaries. Refactoring.guru is specifically cited for its animated walkthroughs; its prose is a second pass, not a first.