One Change, One Place
When a rule lives in one place, changing it is a one-line edit that ripples out correctly everywhere. When it’s copied across five places, changing it is a hunt, and you’ll miss one. This is the difference between a change that trickles down cleanly and a change that scatters edits across the codebase and leaves it inconsistent. It’s the most important structural skill an engineer has, and the one the failure mode at the start of this group fails hardest.
The name for the bad version is shotgun surgery: one conceptual change forces you to fire edits into many scattered spots. The name for the goal is a single source of truth: each fact, each rule, each calculation lives in exactly one place, and everything else asks that place instead of keeping its own copy.
Duplicated Truth Is the Root of It#
What’s expected: A given rule or calculation exists once in the codebase, and everywhere that needs it calls that one definition.
The Storefront computes a cart total. If the price math, subtotal, discount, tax, shipping, is written out on the cart page, and again on the checkout page, and again in the confirmation email, and again in the admin, you don’t have one calculation. You have four, drifting apart from the day they’re born. Add a discount and you must find and fix all four. Miss the email, and shoppers get charged one price and emailed another. Nobody decided to create that bug; it was baked in the moment the math was copied.
// cart.tsx sum(items) - discount + tax // checkout.tsx sum(items) - discount + tax // email.ts sum(items) - discount + tax // admin.tsx sum(items) - discount + tax // change one → hunt for four
// pricing.ts — the one source
computeTotal(cart): Money { … }
// everywhere else, just:
computeTotal(cart)
// change it once → trickles
// to all four, correctly
How to get there: When you notice yourself copying logic, stop, that copy is a future bug. Put the rule in one function, one module, one source, and have every caller use it. Then a discount, a tax change, a currency tweak is one edit in one place, and it flows to the cart, the checkout, the email, and the admin because they all ask the same function. That’s what “trickles down in a good way” actually means: not that you remembered to update every copy, but that there was only ever one.
A caution, from the other side: don’t force two things that merely look alike into one. If the cart total and a shipping estimate happen to share a line of math today but answer different questions, they’ll need to change independently tomorrow; merging them creates a different mess. Single source of truth is about one fact in one place, not one line of code reused by coincidence.
And one more shape: for a rule (how a total is computed) the single source is a function everyone calls. For a value that must not change after the fact (the amount a shopper was actually charged) the single source is a record computed once and stored, then read, not a function re-run on every screen. Re-deriving a past charge from today’s cart is how the email drifts from the receipt. Same principle, one home, two different shapes.
This isn’t only about money. An order’s status, pending, paid, shipped, delivered, is a fact too: if the logic mapping a status to its label and color is copied into the cart badge, the admin table, and the shipping email, then adding a “refunded” state becomes the same four-place hunt with the same missed spot. Any fact the product repeats, a status, a permission rule, a date format, wants one home.
Put the Change Where the Concept Lives#
What’s expected: You make a change at the level where the concept actually lives, not at the screen where the symptom showed up.
The symptom shows up on a page. The cause usually lives deeper. A coder edits the page, because that’s where they saw the problem, and leaves the real rule untouched, so the same bug resurfaces on the next page that uses it. An engineer traces the symptom back to where the behavior is decided and changes it there, once, so every surface that depends on it is fixed together.
This is the code-level version of root cause vs. symptoms. “Discounts show wrong on the cart page” is a symptom. If you fix it on the cart page, you’ve patched one surface. If the real cause is that pricing is computed per-page, the fix is to give pricing a single home, and now the cart, the checkout, and the email are all correct, because you changed the concept, not the screen.
Know the Blast Radius Before You Touch#
What’s expected: Before you change shared code, you know everything that depends on it and have checked your change against all of it.
A single source of truth is powerful precisely because everything depends on it, which means a change there ripples everywhere. That’s the point, and the responsibility. Before you edit computeTotal, you find every caller and ask: does this change do the right thing for all of them? A tweak that’s right for the cart but wrong for the refund path is not done.
How to get there: Trace the callers before you edit shared code (your tools will list them in seconds). For each one, ask whether your change is correct there too. When the blast radius is large, that’s usually a signal to move carefully and lean on tests, not a reason to avoid the shared code and paste a copy. The copy is usually the worse choice, but not always: across a module or service boundary, binding two things that must evolve independently to one shared definition creates coupling that can hurt more than the duplication would. Inside one cohesive area, duplication almost always loses; across boundaries, a little copying can beat the wrong dependency. The tests you wrote for the edges are what make a high-blast-radius change safe: change the one source, run the suite, and every dependent surface tells you at once whether it still holds.
Cohesion: Things That Change Together, Live Together#
What’s expected: Code that changes for the same reason is in the same place; code that changes for different reasons is kept apart.
The deeper principle under all of this is cohesion. A well-organized system groups things by why they change. Everything about pricing lives together, so a pricing change is local and self-contained. When related logic is scattered, one concern smeared across many modules, every change to it becomes shotgun surgery. When unrelated logic is jammed together, one module doing five unrelated jobs, every change risks breaking something it has nothing to do with.
Cohesion’s twin is coupling: how much one part leans on another. A single source of truth deliberately couples every caller to one definition, that’s the price you pay for the power to change it once. It’s a good trade when the callers genuinely share that rule, and a bad one when they only looked alike. So the goal isn’t zero coupling; it’s coupling that follows real shared meaning and stays out of the way of things that need to move on their own.
You feel good cohesion as an engineer directly: a change feels local. You open one file, make the edit, and you’re confident nothing far away just broke. When a change makes you touch nine files across five modules, that’s not just tedious, it’s the system telling you the concept was never given a home. The fix is usually to give it one, so the next change is one edit in one place.