Branching by abstraction
When branching by abstraction, you are not keeping two versions of your code side by side using branches, but you keep them side by side in your code base. For example, when you want to change the implementation of a class called FoodClassifier, which implements the IFoodClassifier interface, you go through the following steps:
- You refactor the name of the FoodClassifier class to FoodClassifierToBeRemoved.
- You create a copy of the complete FoodClassifierToBeRemoved class.
- You name this copy back to FoodClassifier.
At this point, your changes should look like this:
public class FoodClassifier : IFoodClassifier
{
public FoodClassification Classify(Food food)
{
// Unchanged classification algorithm
}
}
public class FoodClassifierToBeRemoved : IFoodClassifer
{
public FoodClassification Classify(Food food)
{
// Unchanged classification algorithm
}
}
Please note that at runtime, your application will behave just as it did before. You have just added a new, yet unused, class with a change in behavior. It is safe to commit these changes and even ship the new binaries to a user. Now you can start changing the implementation of the new FoodClassifier class, test it, and establish trust in its implementation. Meanwhile, you can keep committing and pushing your changes, even to customers. Switching to the new implementation can be done using your dependency injection configuration, a Boolean flag, or environment variables. Just choose what makes sense in your scenario.
Only when you are fully satisfied that the new implementation is working, you remove the FoodClassifierToBeRemoved class and update any references back to FoodClassifier.
We will expand on branching by abstraction in Chapter 4, Continuous Deployment, when discussing feature toggles. While being a recommended way forward to further accelerate your delivery, branching by abstraction is a double-edged sword. If you do not have a process to keep the number of side-by-side implementations under control and clean them up after switching implementations, the quality of your code base might decline.