Branch By Abstraction
7 January 2014
“Branch by Abstraction” is a technique 1 for making a large-scale change to a software system in gradual way that allows you to release the system regularly while the change is still in-progress.
1: This technique has been around for a long time, although it never got a popular name. Paul Hammant introduced the term “Branch by Abstraction” while arguing in favor of Trunk Based Development (he credits Stacy Curl with originally coming up with it). This name seems to have caught on and is now the term I most commonly hear.
We begin with a situation where various parts of the software system are dependent on a module, library, or framework that we wish to replace
We create an abstraction layer that captures the interaction between one section of the client code and the current supplier. We change that section of the client code to call the supplier entirely through this abstraction layer.
We gradually move all client code over to use the abstraction layer until all interaction with the supplier is done by the abstraction layer. As we do this we take the opportunity to improve the unit test coverage of the supplier through this abstraction layer.
We build a new supplier that implements the features required by one part of the client code using the same abstraction layer 2. Once we are ready we switch that section of the client code to use the new supplier.
2: While we are building the new feature we can use FeatureFlags to run the new supplier in test environments and compare its behavior to the flawed supplier.
We gradually swap out the flawed supplier until all the client code uses the new supplier. Once the flawed supplier isn't needed, we can delete it. We may also choose to delete the abstraction layer once we no longer need it for migration.
My description above describes a common case, but there are plenty of variation that can occur. Sometimes you can't swap-out the supplier for only some clients, you have to do it all at once. Sometimes you can break down the features of the supplier into different sub-components and carry out this whole procedure one sub-component at a time.
Despite these variations, there is a common theme. Use an abstraction layer to allow multiple implementations to co-exist in the software system. Use the notion of one abstraction and multiple implementations to perform the migration from one implementation to the other. Ensure that the system builds and runs correctly at all times, so you can continue to use Continuous Delivery while you are doing the replacement. Look for as many ways as possible to make changes gradually.
Further Reading
Jez Humble describes how his team used Branch-by-Abstraction to replace both an object-relational mapping framework (ibatis to hibernate) and the web UI framework (velocity/JsTemplate to Ruby on Rails) for Thoughtworks's Continuous Delivery tool “Go”.
Paul Hammant provides more details of using Branch-by-Abstraction, particularly as an alternative to using version-control branching.
Steve Smith describes a variation which involves verifying that the two implementations return the same results to requests.
Acknowledgements
Thanks to Paul Hammant for his detailed suggestions as well as being an important primary source.Notes
1: This technique has been around for a long time, although it never got a popular name. Paul Hammant introduced the term “Branch by Abstraction” while arguing in favor of Trunk Based Development (he credits Stacy Curl with originally coming up with it). This name seems to have caught on and is now the term I most commonly hear.
2: While we are building the new feature we can use FeatureFlags to run the new supplier in test environments and compare its behavior to the flawed supplier.