Abstraction

An abstraction hides detail behind a useful model, and charges indirection, vocabulary and leakage for it. When to pay, and when duplication is cheaper.

What an Abstraction Actually Is

A useful model that lets a caller ignore something specific. `PaymentGateway.charge()` hides provider HTTP; `UtilityManagerFactoryHelper` hides nothing and is therefore not an abstraction at all.

Q · What distinguishes a real abstraction from a wrapper with an important-sounding name?
What an Abstraction Costs

Indirection, vocabulary, learning cost and leakage — charged to every future reader, forever, whether or not the flexibility is ever used. Do not abstract by default.

Q · What does adding an abstraction cost, and who pays it?
The Rule of Three

A heuristic about evidence, not a counting rule. Duplicate until the pattern is a pattern, because the third case is usually the first one that shows you which parts actually vary.

Q · How much evidence should I have before turning duplication into an abstraction?
Leaky Abstractions

`Repository.save()` claims database independence while transaction scope, isolation level, index behaviour and failure modes come straight through. An abstraction hides a mechanism; it cannot erase the physics underneath it.

Q · Why do abstractions keep failing exactly when they matter most, and what should I do about it?
Premature Abstraction
▶ lab

The wrong abstraction costs more than the duplication it replaced, because duplication is visible and a wrong shared unit is not. Its signature is callers that diverged and a parameter list that grew flags to hold them together.

Q · Why is a wrong abstraction more expensive than the duplication it removed, and what do I do once I have one?
Choosing the Model
▶ lab

An abstraction buys flexibility along one axis and pays along every other. Which axis you pick is not a detail of the design — it is the design.

Q · Given that any abstraction makes one kind of change cheap and other kinds more expensive, how do I choose which kind?