Refactoring

Changing internal structure without changing observable behaviour — as a disciplined loop with a safety net, not a rewrite that someone called a refactor.

What Refactoring Actually Is

Changing internal structure without intentionally changing observable behaviour. Almost everything called a refactor is something else, and the difference is what makes it safe.

Q · What separates a refactor from a rewrite, and why does the distinction decide how the work should be done?
The Refactoring Loop

Working code, a safety net, one small transformation, verify, repeat. The discipline is entirely in the size of the step and in never being more than one step from working.

Q · How do I restructure code that is in production without ever being in a state I cannot ship or abandon?
Extract Function

Extract to give a meaningful concept a name, not to reduce a line count. The two motivations produce different code, and only one of them helps.

Q · When does pulling a block of code into its own function make the code easier to change, and when does it just move the problem behind a name?
Extract Module

Pull out a module when a set of responsibilities has become cohesive enough to have its own reasons to change — and its own interface that hides them.

Q · How do I know when a group of functions has become a module, rather than just a folder I put them in?
Rename

The highest value-to-risk refactoring there is, and the most neglected. A better name is a better model, and the cost is usually one command.

Q · Why is renaming a thing worth a pull request of its own, when it changes no behaviour at all?
Move Responsibility

If a piece of logic spends its time reaching into another object's data, it probably belongs to that object. Moving it is usually the cheapest coupling reduction available.

Q · How do I tell whether a piece of logic is in the wrong place, and what does moving it actually buy?
Replace Conditional With Polymorphism

Worth doing when the variation is stable, meaningful and repeated across several operations. Not worth doing to most switch statements, where the switch is clearer than what replaces it.

Q · When does turning a conditional into a set of types make the code easier to change, and when is the conditional simply the right answer?
Introduce Parameter Object

Bundle arguments that travel together and mean something together. Bundling them into a vague `Options` bag because there were too many is how a long parameter list becomes an untyped one.

Q · When does grouping arguments into a type make a signature clearer, and when does it just hide the count?
Refactoring Without Tests

Sometimes you have to change code whose behaviour nothing protects. The technique is a small number of provably-safe moves, used to buy a seam, used to get a characterization test in place.

Q · The code has no tests, I cannot add tests without changing it, and I have to change it. Where does that loop break?