Programmer’s Journal: Refactoring
One of our most recent changes was revisiting themes. Adventure Cow has support for custom story themes – by writing your own HTML and CSS, you can create a new look for the same story. Since this functionality has been developing since a very early stage with Adventure Cow, it’s had time to accumulate dust.
When I lifted the hood on the CSS, I found a number of unpleasant surprises – tangled dependencies 4 layers deep on stylesheets that seemed unrelated and the like. (If you’ve ever managed a WordPress blog, imagine WordPress themes not being in their own folder, but sprinkled all over the rest of the WordPress directories. Yeah, it was like that.)
Deciding it was time for a refactoring, I sorted it out so now instead of three different directories for styles, there’s one, and instead of placing stylesheet files in random places, each theme has its own folder. Hooray!
Unfortunately, not every refactoring ends well. You wouldn’t be refactoring if you weren’t starting out with code that was hard to understand in the first place, which makes the challenge somewhat greater. Some thoughts I had while on my two day sojourn:
Your goals should be radical, but your methods should be modest
When I started refactoring, I knew what I wanted: each theme in its own folder. I knew this method would be far neater, and easier to manage than what had come before. Prior to this refactoring I had done a number of tentative, part-way steps. The problem with only partially fixing the problem is that if you’re not careful, it can come back.* By leaving old stylesheets, scripts, functions, whatever, in the wrong places, you run the risk that those places will look like valid places to add new functionality, thus adding to your original problems.
You can always put big flashing warning signs around bad old code, thus reducing the risk that someone will accidentally reinvigorate the existing problem, and doing that indeed bought me some time. However, without a sense that there indeed was a bigger goal, I would’ve been trimming around the edges, without any real benefit to my future coding speed.
On the other hand, don’t expect to tear out every file at once and put them all back in and expect everything to work. (You’ll have better luck if you have unit tests, but still.) Nothing’s worse than radically changing every single file, finding that it doesn’t work, and then having to roll the entire thing back. If you can take your ambitious, world-changing effort, and break it into a series of low-risk, simple changes, you will both increase your long term benefit and reduce your short term risk.
Take good notes
It’s not always possible to make everything a small change. I sometimes found sections of code where multiple units were tied together. Each thing I fixed seemed to carry the seeds for four different other necessary simultaneous fixes, and very few changes seemed to be possible without changing everything else at once.
This is where it helps to write down what you’re working on and how the system is structured. If you’re refactoring a system, most likely it doesn’t have the greatest organization now. The notes you take will form the backbone of the better system you’re transforming the current one into.
November 19, 2013 Tuesday at 11:41 pm