Paul Hammant's Blog: Avoiding 'Big Bang' for Branch By Abstraction
Jez Humble linked back to me on his experience report for BBA (thanks Jez). Ironically, he’s performing the change from iBatis to Hibernate which is the opposite of the hypothetical case that I’d made some years ago.
After reading his article and seen some field usage of BBA, I wanted to say some more.
Avoid big bang
If you can help it, you should not do the cutover from A to B in a big bang. Imagine you had a set of components that you needed to change in some way, that was going to take some weeks to code. Perhaps a longer time than your production release interval. Say that was three months, and your team was in the habit of pushing production releases monthly like clockwork.
Strategy A (big bang)
1) You take your starting set of components like so
2) work over three months to get them all in the finished state. Commit to trunk of course, but provide a feature toggle that is ‘old implementation’ for everyone on trunk, and the two production release branches that were made from it, with only yourself and a CI build pipeline as seeing the ‘new implementation’. Like so:
3) When finished, and everyone agrees, then flip the switch (toggle) for everyone (including the next live release). Then, when that has been in production for a while, remove the switch and the old implementation (and perhaps the abstraction if it was not useful for unit testing):
Strategy B: Iterative instead of Big Bang
Instead, how about an iterative approach where components are turned on as they are completed. You would be forcing all developers to take the changed implementation, and production releases that go out. You would not need to hold on to the old implementation as long, and the switch/toggle is somewhat less magnificent. This feels safer to me.
The less than magnificent switch/toggle is still there of course, but it only concerns the single component that you’re currently working on. At any moment in time, as viewed by everyone else on trunk, or the folks concerned with releases, some components have the old implementation, and some have the new ones. Over the three months the transition is completed, and everyone gets to use the new implementation as it is progressively rolled out.
Of course, you still need to introduce the abstraction throughout the codebase before you start to change the first implementation.
The benefits of this approach?
You are able to defuse these allegations:
“you’ll never finish”
“devs in other teams are still making old implementations, therefore you new version is at risk”
“there is too much at risk for the big bang, as it has never been tested properly”
Agile teams and BBA
There’s some responsibility needed using BBA in Agile teams. Practitioners of XP (and alike) are bound to love refactoring. There’s going to be pain from merging to working-copy as much as there is to any branch (all SCM tools to variable degrees irrespective of workflow). Therefore responsibility is needed. If someone wants to rename every and package to fit with some new understanding of the application, then you have to be 100% sure the thing is going to merge to whatever developers don’t have committed. Git (and alike) hit the new high-bar of SCM, merge through rename , quite well so could cope, but lesser SCM tools might not. If you understand that refactoring is not refactoring+make some other changes, then it might be polite to notify developers that you’re about to to a big rename/move thing and they might want to a) checkin stuff they are doing if timely, and b) go to lunch.
Ball of Mud vs Hairball
Jez cites Brain Foote’s ball of mud article. I’ve met Brian a couple of times, and he’s engaging and entertaining , but I’m not sure that ball of mud is the right metaphor for the entanglement we see in enterprise application development. I think ‘hairball’ is. Imagine the thing a cat coughs up, with implicit horrific entanglement.