Compatibility and Evidence for Design Changes
What This Concept Is
A design change should name what remains observable to clients. Include return values, errors, state mutations, ordering, iteration behavior and documented resource guarantees. Test observations at the public boundary before comparing class diagrams. A bug fix or new validation may be worthwhile, but it deliberately changes behavior and should not hide inside a claimed behavior-preserving refactor.
Why It Matters Here
The legacy fixture contains defects worth repairing. Keeping an explicit record of intentional changes prevents a passing new test suite from erasing evidence about old callers. Module 2 will build on this distinction when teaching mechanics.
Concrete Example
The legacy renderer writes a header before consuming rows. A new renderer first validates all rows and writes one complete string. With valid finite inputs, both may produce similar text; on a late iterator failure, one leaves partial output and the other makes no write. Escaping names also changes emitted bytes for input containing '<' or '&'. Document these as accepted contract changes with exact before/after cases. Keep a valid unaffected example to check compatibility.
How To Use It
- Record the change pressure and a small failure or costly edit.
- Freeze public observations and distinguish intended changes.
- Compare the smallest candidate with keeping the current design.
- Run behavioral and failure-path checks; test new assumptions.
- Exercise one changed requirement and inspect the resulting edit surface.
- Record costs, uncertainty and a revisit trigger.
Common Confusion / Misconception
Do not infer design quality from fewer lines, classes or comments alone. A timed change exercise is influenced by familiarity and learning order; report it as a case study unless your design supports a broader causal claim. Tests over a finite domain support the implemented versions. Future implementations and external clients still need contracts and review.
Check Yourself
Which old observation changes when output is buffered? Which consumers can a compiler miss? What evidence would reverse your proposed design decision?
Mini Drill or Application
Practice: rename an exported field used as a serialized key. Identify a consumer a compiler might miss and propose a compatibility strategy. Feedback: stored documents, reflection and external clients may retain the old spelling; an alias, explicit migration or versioned boundary is needed depending on ownership.
Read This Only If Stuck
Use Refactoring's book index to locate “Defining Refactoring and The Two Hats”; exact local locator is in the reading guide. Module 2 develops the mechanics of small safe changes.
Use the design contracts and labs to turn these claims into evidence.