Skip to content

Design for Change

Some changes are probable: a new payment provider, a different database, a new external system. Architects can prepare for these ahead of time. The aim is to make the affected part cheap to change when the day comes.

Prepare, do not build early. Preparing for a change differs from building the feature now. YAGNI (“you aren’t gonna need it”) warns against building presumptive features. Such features add complexity, and that complexity makes software harder to modify and debug. YAGNI covers capabilities built for a guessed feature. It does not cover work that makes software easier to change, such as refactoring, tests, and continuous delivery. YAGNI itself only works if the code is easy to change.

Hide outside systems behind one interface. The Gateway pattern wraps an external system behind a simple interface. Without it, the external API spreads through the code. Then a change, such as swapping a database for XML, becomes much harder. With a gateway, one place changes.

Make change scenarios concrete. arc42 recommends writing change scenarios. They cover maintainability, modifiability, changeability, and flexibility. One example turns a likely change into a measurable requirement: integrating a new external payment provider takes at most two person-weeks.

Keep parts independent. A quality requirement can express loose coupling (see the Loose Coupling article). Changes to one subsystem should be possible without touching the others. arc42 also treats extensibility, the ability to add features, as a goal. Plugin and event-driven architectures support it.

Spend flexibility with care. Flexible frameworks and components cost extra up front, and the payback comes later. XP advises not building them for the first case that needs the functionality.

A team expects to replace its payment provider someday. It does not build support for three providers now. It puts all provider calls behind one payment interface and writes a scenario: a new provider must be integrable within two person-weeks. Only that one interface would change later.

Planned flexibility helps only for anticipated changes. It may hurt for unforeseen ones, because unneeded complexity makes the system harder to change in every direction except the expected one. Guessing future needs often goes wrong, especially without detailed requirements. Working on the wrong flexibility early is even more wasteful than working on the right one early. Keep flexibility to the likely change spots, and keep the code easy to change so you can add the rest later.

  • Likely changes are written down as change scenarios, such as a new external provider.
  • At least one change scenario has a measurable limit, such as effort in person-weeks.
  • External systems are accessed through a single wrapping interface, not called directly across the code.
  • Flexibility is built only for foreseeable changes, not for guessed features.
  • Independent change of subsystems is stated as a quality requirement.