Do you have to choose duplication, paralysis, or chaos?
Johannes Brodwall wrote
a blog with this title on a subject that has interested me for a long time: How to avoid chaos and support stability in face of a constantly changing interface (my rephrasing). He sketches three different approaches:
- Duplicate code, so that change at one place does not affect code somewhere else, but at the cost of duplicated changes of common logic
- Share code, to avoid duplicated changes of common logic, but at the cost of requiring change in all the clients when the logic of any of the suppliers changes
- Do not allow changes, to avoid both of the inconveniences above, but at the cost of conserving unsatisfactory solutions
I tend to think that the solution will change over time.
- Initial code is unstable and has only a few clients. Apply approach 2.
- As code matures and stabilizes, fix its contract (precondition and postcondition). Apply rule 3 and the open/closed principle.
- A subsequent change may of may not break the contract.
- If it does not (weaker precondtion, stronger postcondition), there is nothing to worry about - clients are not affected by the change. All tests will pass unchanged.
- If it does, apply rule 1 and define a new function for the new contract, possibly making the old definition deprecated to leave a transision time for the clients.