Composing Methods
Intent
Section titled “Intent”The composing methods family is about the inside of a function: how its statements are grouped, named, and ordered. These refactorings do not change behaviour. They change how easily a human can follow what the function is trying to say.
The smell
Section titled “The smell”A function grows over time. It accumulates a temporary variable here, a clever one-line condition there, a loop that quietly does three jobs. Eventually nobody can read it top-to-bottom and explain it in a sentence. The cures in this module attack that directly: they pull tangled fragments apart, give the important pieces names, and let the leftover code read like a short summary of intent.
| Smell (Fowler, ch. 3) | What you notice | Move |
|---|---|---|
| Long Function | A function you cannot summarize in one sentence | Extract Function |
| Duplicated Code | The same logic copy-pasted into several places, bugs included | Extract Function |
| Mysterious Name | A sub-expression whose meaning you have to decode | Extract Variable |
| Mutable Data | A temp that pins a computed value inside one function | Replace Temp with Query |
| Divergent Change | One function doing two unrelated jobs, so a change to one touches the other | Split Phase |
| Loops | An imperative loop that mixes filtering, mapping and accumulating | Replace Loop with Pipeline |
flowchart TD
A["A long, tangled function"] --> B{"What is wrong?"}
B -->|"A block does one named thing"| C["Extract Function"]
B -->|"A helper adds no clarity"| D["Inline Function"]
B -->|"A sub-expression is cryptic"| E["Extract Variable"]
B -->|"A temp holds a computed value"| F["Replace Temp with Query"]
B -->|"Two unrelated jobs in one flow"| G["Split Phase"]
C --> H["Code that reads like intent"]
D --> H
E --> H
F --> H
G --> H What this module covers
Section titled “What this module covers”Nine refactorings, each small and reversible:
- Extract Function — lift a fragment into its own well-named function so the caller reads as a list of intentions. The most fundamental move of all.
- Inline Function — the inverse: when a helper’s body is as plain as its name, fold it back in.
- Extract Variable — give a confusing sub-expression a name so the line explains itself.
- Inline Variable — the inverse: delete a variable that only echoes its expression and adds no clarity.
- Replace Temp with Query — turn a local that holds a computed value into a function, so the calculation is reusable and easy to extract.
- Slide Statements — move related statements together so a coherent fragment sits ready to read or extract.
- Split Phase — when one block does two different jobs, separate them into ordered phases joined by a clear intermediate value.
- Substitute Algorithm — replace a convoluted way of doing something with a clearer one that yields the same result.
- Replace Loop with Pipeline — convert an imperative loop into a chain of named stages — filter, map, reduce.
Each lesson shows the same before-and-after in TypeScript, Python, Go, and Rust, then walks through the safe, ordered mechanics — running your tests between every step.