Multiple consumers compute the same derived values from the same source data, each independently re-deriving the result.
Multiple derived values from the same source come from one transform that produces an enriched record.
Before the refactoring
function baseCharge(reading) { return reading.kwh * reading.tariff.baseRate; }function taxableCharge(reading) { return reading.kwh * reading.tariff.taxRate; }// every consumer recomputes:const monthly = baseCharge(reading) + taxableCharge(reading);const discount = baseCharge(reading) * 0.95;
After the refactoring
function enrich(reading) {return {...reading,baseCharge: reading.kwh * reading.tariff.baseRate,taxableCharge: reading.kwh * reading.tariff.taxRate,};}const r = enrich(reading);const monthly = r.baseCharge + r.taxableCharge;const discount = r.baseCharge * 0.95;
Derivations drift between consumers as they age; bugs hide where two consumers compute slightly different versions; performance suffers from redundant computation.
Building a transform up-front when only one derivation exists is BDUF — wait for the second derivation before introducing the transform.
Derivations stay consistent (no two callers compute slightly different versions); cache invalidation becomes obvious.
Building a transform up-front when only one consumer derives anything — BDUF abstraction that adds an intermediate type without an active second user.