If some part of the codebase needs to be changed, you first find the entry point to this part—a seam—and put in an abstraction layer which delegates to the current implementation. You then develop the new implementation alongside the new one. Which implementation gets used is decided by a configuration option that can be modified at deploy time or even run time.

