We want to be able to grow our domain models. They must be infinitely scalable. Growing an already large model should not be more difficult than a small model. Change comes in two forms: changing existing functionality, or adding new. We want there to be as little difference as possible between the two, regarding testing, validating, and modelling.
Also Known As
No known current variants of this pattern are known to me.
A banking system has functioned for years but now an invasive change is necessary: the format of the account numbering system needs to change from a proprietary 9-digit number to a standardised 20-digit one. Since this change will impact all existing accounts it seems to be a daunting job: all accounts will be touched, and this change may have numerous side effects. It may even be impossible to cover all test cases completely.
Don’t change existing objects. Not for changing existing functionality, nor to add new functionality. Existing test cases should not need to be modified. Instead functionality is modified by adding more objects. Since the model has been created using the Active/Passive pattern it is a loosely coupled model that does not hinder us in doing this.
Existing objects will still be used by the existing part of the system. However new parts, those that need to work with the new format, will “enhance” those existing objects by reusing them. This is done by wrapping the existing bank accounts in a new bank account object, delegating all necessary behaviour to the existing object, but (as it were) enriching the object with the new behaviour.
The Decorator pattern from the Design Patterns book. In fact this is the possible implementation of this pattern.
- Changes do not lead to mandatory changes to existing components
- Test cases do not need to be modified (same rule applies: change will lead to new components, in this case test cases, not to changes to existing components, in this case test cases)
- The system may only grow, this is a possible adversary effect of the applying the pattern. As with any pattern, it is not applied in isolation: you will still need to audit your solution for legacy migration, which will phase-out obsolete parts of the system.