"Lean" Refactoring

  • : Function ereg() is deprecated in /home6/alailima/public_html/tigretigre/includes/file.inc on line 895.
  • : Function ereg() is deprecated in /home6/alailima/public_html/tigretigre/includes/file.inc on line 895.
  • : Function ereg() is deprecated in /home6/alailima/public_html/tigretigre/includes/file.inc on line 895.
  • : Function ereg() is deprecated in /home6/alailima/public_html/tigretigre/includes/file.inc on line 895.
  • : Function ereg() is deprecated in /home6/alailima/public_html/tigretigre/includes/file.inc on line 895.
  • : Function ereg() is deprecated in /home6/alailima/public_html/tigretigre/includes/file.inc on line 895.
  • : Function ereg() is deprecated in /home6/alailima/public_html/tigretigre/includes/file.inc on line 895.

I've written elsewhere about Lean software practices, but I'm actually going to take on a different meaning of the word today. You may, like me, be presented with a large heap of old code, some of which reeks so thoroughly of rot as to make the gods on high spew their ambrosia. How to clean these Augean stables might seem a Herculean task. However, turning the course of the river can actually done bit by bit, in fabulous Lean fashion, to deliver incremental benefits that move you closer to your end goal.

You need to gracefully shift the center of mass (just as I am hopefully shifting metaphors gracefully). A legacy codebase has a great deal of inertia, but any living program needs constant additions and modifications. As in my go/Lean post, I sometimes view requirements as my opponent. So in this little scene, let us imagine a big burly sumo bearing down on you. Victory, it seems, is within his mighty grasp. But wait, the judo-master developer has, through a series of twists and turns, subtly knocked the giant on his massive rear! I don't believe it folks, David has bested Goliath, without even a stone to throw!

How can you become this judo master? First off, you need foresight. You need to know where you want things to end up. Ideally you could come up with the broad strokes of a few steps, possibly large ones, that would get you there. But ultimately, nothing is going to happen unless you can come up with small, easily executable steps that change the game in your favor. The more you can offload work or data from unsavory legacy structures onto new ones that bear the mark of the end goal, the more things start to tilt in the direction you're looking to move. It may seem counter-productive to potentially duplicate what's there, albeit in better fashion, but that's the only way to make the old redundant and expendable. Once the weight is lifted off of the old stable but untenable foundations onto newer, shaky but more desirable jacks, you're really moving towards a better place. So this, at last, is the punch line of this post. The key to moving the mountain, is to "lean" it in the direction you want it to go. Dig a little under one side. Lift the other side up a little. Pretty soon, you'll have nothing to do but keep up with the mass in motion.

I would be remiss if I didn't mention one practical tool to help you on your journey. A coworker recently pointed me to the Mikado method, which exemplifies the incremental approach to large-scale refactoring. I haven't tried it quite like this, but I am used to the principles and agree that applying them in this fashion would tend to make the seemingly impossible actually quite manageable.


I realized that this post was largely a cheerleading effort, with a dearth of concrete examples, but I happened upon a good example just today at work. We have a significant legacy codebase which plays several mission-critical roles. But there are understandably some parts that we'd like to be rid of. Over time, we've built up a parallel infrastructure that has taken on more and more of these roles. But to mitigate risk, we often do something like what I did today:

  1. Duplicate the main functionality that we want to keep in the new structure
  2. Possibly run both in parallel until we have established that the new can take over for the old
  3. Remove the old functionality, possibly leaving a thin wrapper in place to maintain temporary backwards compatibility
  4. Migrate all invocations of the wrapper to use the new structure directly

Four simple steps, none of them overwhelming to take one at a time, but together they work wonders in eliminating the albatrosses of ancient code. I've applied this pattern numerous times, but each time I finish the last step I feel a great burden has been lifted off of me.

Trackback URL for this post:



Another image

A coworker, referring to something I wrote yesterday which was a similar application of these principles, said he like the "beachhead" I had established in an older code structure for a newer component. Being a man of many metaphors, especially enjoying the strategy-related ones, I thought I'd share that. I don't care what imagery you use. Just take the opportunities you are given to make the world a better place.