Inline duplication is sometimes cheaper than the wrong abstraction
Aliases: duplication cheaper · local copy · split the wrong share
What it is
Two pieces of UI that look alike today need not remain one module tomorrow. Once they are pulled into a shared implementation, every real difference on either side has to walk through the shared interface and become a switch, a special-case branch, or “change the share and hope the other side is fine”. Inline duplication leaves two copies next to their call sites; the radius of an edit stops there. When the shared abstraction already fails to match the roads the two sides will take, the total hours of copying — including the times both sides do have to change — can still undercut the hours of keeping the wrong share. Cheap means radius of change and radius of understanding, not fewer keystrokes.
Duplication is not a virtue. It is choosing a smaller radius once the cost of “extracted wrong” is visible. A right share is still cheaper; this is about the wrong kind.
Why it happens
A wrong share welds two future forks together. One side needs keyboard shortcuts, the other needs to become a non-interactive display; the shared module must express both mutually exclusive fates, so it grows parameters nobody really owns. Every edit regresses both sides, even when the demand came from one. When regression fails, each side blames the other for “breaking the share”. The cost is coupling, not line count.
Inlining cuts the coupling. One side changes the keyboard; the other’s display may not even recompile. Those dozens of “wasted” lines buy an independent failure domain. When the two sides’ rate of difference exceeds their rate of sameness — every iteration forks, and “a patch both truly need” is rare — net spend on copies is lower. Sharing pays only while sameness stays faster than difference; once the direction has reversed, more switches are compound interest on the wrong abstraction.
Where it stops holding
Kernels that must be identical across products and whose difference-rate is near zero — accessibility synthesis, focus rings, contrast maths — turn duplication into bugs immediately: focus fixed on one side, forgotten on the other. Copying applies to product semantics, not those kernels. Legal copy and security notices that must match word for word will leak a missed edit if duplicated; they need a single source. When two sites are already patching the same defect in parallel and the patches start copying each other, sameness-rate has returned: extract, but along the patch boundary, not back into the wrong large module. Two generated outputs that look alike with one source are not inline duplication; do not “dedupe” generated artefacts by hand.
Applying it
- Before extracting, write two columns: what each side will certainly change in the next three iterations, and what both must change together. If the first column is longer, copy, don’t extract.
- A share already extracted wrong may be legally split back: copy the module next to both calls, delete switches that existed only to accommodate the other side, then edit separately. Mark the change “dissolve a wrong share” so it is not treated as a regression.
- Keep a whitelist of kernels that must be single-source (focus, contrast, name synthesis); review refuses copies of those into product files.
- How to check: open the shared module and count branches that exist for “only one side needs this”. If that count exceeds behaviours both sides truly share, the abstraction is losing. Rehearse an A-only change: if B must be regressed, or the share must grow a switch, copying is cheaper. After a split-back, an A edit must not trigger B’s tests — that is the failure domain coming apart.
Related
- Same group: R1.17.1 The more generic a component's name, the easier it is to dump unrelated duties into it · R1.17.2 Extra indirection added for reuse raises the cost of understanding
- Adjacent: R1.08 Premature abstraction · R1.02 Component library and variants
- Search terms:
inline duplication cheaper than wrong abstraction·duplication cheaper·wrong abstraction