Incorporating Change

Learn about substituting, augmentation and excluding, inversion and porting, also how to make the system more adaptable.


Given a modular design, substituting is just replacing one module with another, like swapping out an NVidia graphics card for an AMD graphics card or vice versa.

The original module and the substitute need to share a common interface. That’s not to say they have identical interfaces, just that the portion of the interface needed by the parent system must be the same. Subtle bugs often creep in with substitutions.

In our running example, we might substitute a logistics module from UPS or FedEx in place of our original home-grown calculator.

Augmenting and excluding

Augmenting is adding a module to a system. Excluding is removing one. Both of these are such common occurrences that we might not even think of them as design-changing operations. However, if we design our parent system to ensure that augments and exclusions are first-class priorities, then we’ll reach a different design.

For example, if we decompose our system along technical lines we might end up with a module that writes to the database, a module that renders HTML, a module that supports an API, and a module that glues them all together. How many of those modules could you exclude? Possibly the API or the HTML, but likely not both. The storage interface might be a candidate for substitution, but not exclusion!

Suppose instead we have a module that recommends related products. The module offers an API and manages its own data. We have another module that displays customer ratings, another that returns the current price, and one that returns the manufacturer’s price. Now each of these could be excluded individually without major disruption.

The second decomposition offers more options. We have more places to exclude or augment.


Inversion works by taking functionality that’s distributed in several modules and raising it up higher in the system. It takes a good solution to a general problem, extracts it, and makes it into a first-class concern.

In the following figure, several services have their own way of performing A/B tests. This is a feature that each service built…and probably not in a consistent way. This would be a candidate for inversion. In the inversion example figure , you can see that the “experimentation” service is now lifted up to the top level of the system. Individual services don’t need to decide whether to put a user in the control group or the test group. They just need to read a header attached to the request.

Get hands-on with 1200+ tech skills courses.