Refactor in Parallel

As a programmer, most of your work is straightforward. You make small changes, test, and then check them back into the main codebase. This process usually takes a day or days.

However, when working with another programmer, this model doesn't work. You need a shared version of your work. To solve this, you create a new branch in your source code control system. This branch starts from the main branch, but soon diverges as you work together.

You'll occasionally merge changes from the main branch into your branch to stay up-to-date with the rest of the team. Once your work is complete, you'll merge once more, test, review, and then check it in.

The Bumpy Road

This standard approach works, but it has its problems.

Integrating changes from the main branch can be difficult. Team members may not be aware of changes on a branch, causing conflicts when they break your work. This can be annoying, troublesome, or even painful.

Reworking the old system in place can lead to confusion. With each change, it's harder to distinguish original code from added features. Keeping a copy of the original source or referring to diffs is a hassle.

Large teams face another challenge: keeping up with frequent changes. Conflicts can arise from changes to core files or files called from those files. With many team members checking in changes, integrating changes can be overwhelming.

Branching provides flexibility, but it's easy to get lost in a tangle of branches. We've tried alternatives after experiencing pain with the standard approach. One approach we've had success with is the "duplicate-and-switch" model.

Build an Asynchronous System

Instead of changing a system, we build a new parallel one. The new system is developed while the old one is still in use, but only for a small team. Once it's ready, we switch to the new system for everyone. Then, we remove the old system from the project.

This approach helps implement a great tip from Kent Beck: "Make the change easy, then make the easy change." For big changes, this means doing the hard work of building the new system, which makes the switch easy.

When to Use Parallel Refactoring

Parallel rework is a useful approach, but it's not a solution for every problem. You'll still encounter occasional bugs that need fixing in two places. And, if not everyone is using the new version, your work might get broken.

This approach also adds some overhead. You'll need to manage multiple versions of the same concept, which can be a hassle. You'll likely end up writing more code by duplicating parts of the original solution.

If the new system is too different from the original, parallel rework might not be practical. If you can't define a switch between old and new versions, the technique won't work.

However, in many cases, parallel rework allows you to make significant changes incrementally and safely.