I have asked myself for months, how does Google Chrome put builds out so quickly? They have a good number of developers and started with an old fashion version control system like SVN (though looks like git is being utilized now), and they put out builds every two weeks!
Build For Disable
Build feature sets so that they can easily be disabled so that incomplete features can still be continuously integrated.
This idea has intrigued me since I first read it. In nearly all development life cycles, code not ready, or features not ready are simply never merged into the production builds. This makes merging more and more difficult the longer the feature takes to complete. This causes the developers of the long-winded feature to constantly be adapting to other developers code while those other developers never are adapting to the big features until they are ready for prime time. Why can’t we continuously work together?
As developers it has been hammered into our brains that incomplete code, commented code, untested code should NEVER be checked in… It is a developer taboo that we should never do this as professionals. I think we are somewhat ignorant for going along with this for so long. Though I am not saying the opposite is the answer but lets consider how we can utilizing these taboos to really accelerate development cycles.
Purpose of Build for Disable
The primary focus of benefit would be the integration phase of a development cycle; where developer’s code ‘somehow’ merges into the main builds. Many teams have designated integrators who coordinate different branches/repos of the code that have complete functionality and merge those into the main build. This process is very time-consuming for the integrator(s) and also requires a smart, strongly versed, developer of the application to know the side effects of merge conflicts. An alternate approach is often referred to as the definition of continuous integration where when a developer (or small team) is complete with a feature, they merge their own code into the main builds (head/trunk etc). This puts a lot of responsibility on individual developers and can be a race to merge first/early in a development cycle. However, as stated above, developers working on the big features have to be adapting to the baseline without any reciprocal adaptions from the team.
So, work into your development cycle for integration of complete features AND integration of incomplete features that have been disabled. The major benefits of this is merging becomes a smaller and smaller problem. With tools like Mercurial and Git merging has come a long way, however does not solve an agile, frequent build project where features take weeks, but a new build is going out every two weeks.
This process should eliminate duplicate code/effort. Agile processes focus on frequent scrums to keep everyone on the same page, maximize productivity and to reduce duplicated efforts, however this is on a per team level and propagates up the corporate ladder. Why not propagate that idea down into the concrete code. We can see where developers are at on features. We can help each other finish functionality, complete unit tests, all without having to meet and discuss how they will merge together. We can constantly be working together without having to know every detail of each others tasks.
Other Ways How Build for Disable can Benefit the Application and the Team
To build a feature so that it can be easily disabled either by app configuration or commented out code will require some thought into how to call that feature which may lead to better design patterns. If the command pattern is being utilized in an application it can be as simple as disabling the command map. If the feature is called from multiple places, maybe you implement the command pattern or a more streamlined trigger.
Maybe all it takes to disable a feature is to comment out the UI calling that feature and the incomplete code can be continuously integrated with the changing application. The first thing I thought was, well now there’s code that exists that probably doesn’t work, how do I know when I call that code? Well I assume we are all practicing some kind of test driven development. Or at least we test our features. When you come across a feature that does not work, update it and make it work. You were going to have to write that feature anyway. Now you and the other guy working his incomplete feature has a completed function that you both are using, versus two separate implementations of the same thing.
Risk of Build for Disable
There is the obvious difficulty in creating features that can be disabled, and the attempts to disable pieces may just cause chaos. Example: A feature is disabled last minute as it was not ready to go, but that particular method of disable has now broken different functionality that relied on that code. I see this as the most common problem run into initially while experimenting how to disable features. So see previous sections on how to implement build for disable. Also note, the unit test should fail as soon that feature is disabled so it should be caught early.
The Everlasting Gobstopper of Code: Commented code is often the oldest/least changed code in the baseline because every other developer says “I don’t know why that’s there, I am not going to touch it.” This problem is also generalized into removing ‘TODOs’ from code as it is better to track those needs in a Jira(or other) task. I see this as an opportunity to evolve. I agree that everlasting gobstopper comments exist and can cause confusion. But with strong unit tests we have a high level of confidence in changing code, including commented code, and our powerful source control means we are not erasing anything. We can communicate via comments to allow for fast, continuous development, versus the bad comments of describing what the code does, which should be refactored into self documenting code.
I don’t have success or failure stories of this approach. I caught wind of the idea from Google Chrome and watching the commit logs of their releases. This approach would not work well or for all projects, and may not be needed for many projects. For projects with high pace build cycles this is one of those ideas that makes a lot of sense to do yet teams just don’t do it. One of those feelings we have about Pair/Extreme Programming, it makes sense, why can’t the entire team just jump in the deep end and give it an honest try.