If you’re tired of reading articles about feature toggles, rest easy as this is the last one I have planned.
I write a lot about clean code. The central focus of those articles is on how to write code that is easy to read and easy to maintain. Increased readability comes from a variety of techniques, one of which is reducing the amount of conditional logic in code. Because feature toggles increase the amount of conditional logic in code, one could argue that they are the enemy of clean code.
It’s true. Feature toggles add conditional complexity and decrease the readability of code. That puts me, as an advocate of both feature toggles and clean code, in a bit of a tough spot. How do I justify the added complexity of feature toggles when there are well established patterns for feature branching in source control. My justification is that feature toggles are less complex and less error prone.
First, branching of any kind is complex. Whether it happens in code or in source control, there are mental gymnastics associated with keeping branches straight. By keeping as much of the branching in one place (the source code) as possible, you minimize the switching of contexts between source code and SCM. Context switching is a much bigger productivity killer than a single line of added conditional complexity in a source file will ever be.
Second, feature branches are anathema to continuous integration. If you have feature branches YOU ARE NOT CONTINUOUSLY INTEGRATING. The changes on each branch are not compiled with or tested against the changes on all of the other branches. By keeping all of the features together on a single branch, you are testing all of the code together continuously. Testing feature-toggled code does present its share of challenges, but I covered some of those in my last post.
Certainly, there are plenty of people who favor the feature branch strategy. I welcome discussion of the relative merits of toggles vs. feature branches. We’ve done both at Rally and while toggles have their own set of issues, they’ve been pretty successful for us.
Finally, feature toggles reduce the pain associated with merging. This is a bit of a continuation on the continuous integration point, but it’s important enough to be called out on its own. Feature branches require merging at some point. Git is a fantastic tool for branching and merging, but even it has some problems. Merge conflicts are inevitable, especially when refactoring. Martin Fowler has a fantastic article on his bliki about one such challenge.
Despite all those arguments against feature branches, we still use them. Sometimes a change is invasive enough that it can’t be toggled. If putting in code to check your toggle feels like shotgun surgery, a feature branch might be a better choice. You’re going to have merge conflicts if the branch runs for a while, but dealing with those might actually be less work than adding (and subsequently) removing the toggle.
Feature toggles are a powerful alternative to feature branches. There are many times where the added code complexity is a worthwhile tradeoff for an overall gain in productivity. Think about which approach would work best for you.