Objections to Refactoring
Here’s part 8 of the ongoing serialization of Refactoring HTML, also available from Amazon and Safari.
It is not uncommon for people ranging from the CEO to managers to HTML grunts to object to the concept of refactoring. The concern is expressed in many ways, but it usually amounts to this:
We don’t have the time to waste on cleaning up the code. We have to get this feature implemented now!
There are two possible responses to this comment. The first is that refactoring saves time in the long run. The second is that you have more time than you think you do. Both are true.
Refactoring saves time in the long run, and often in the short run because clean code is easier to fix and easier to maintain. It is easier to build on bedrock than quicksand. It is much easier to find bugs in clean code than in opaque code. In fact, when the source of a bug doesn’t jump out at me, I usually begin to refactor until it does. The process of refactoring changes both the code itself and my view of the code. Refactoring can move my eyes into new places, and allow me to see old code in ways I didn’t see it before.
Of course, for maximum time savings, it’s important to automate as much of the refactoring as possible. This is why I’m going to emphasize tools such as Tidy and TagSoup, as well as simple, regular-expression-based solutions. Although some refactorings require significant human effort—converting a site from tables to CSS layouts, for example—many others can be done with the click of a button—converting a static page to well-formed XHTML, for example. Many refactorings lay somewhere in between.
Less well recognized is that a lot more time is actually available for refactoring than most managers count on their timesheets. Writing new code is difficult, and it requires large blocks of uninterrupted time. A typical work day filled with e-mail, phone calls, meetings, smoking breaks, and so on sadly doesn’t offer many long, uninterrupted blocks in which developers can work.
By contrast, refactoring is not hard. It does not require large blocks of uninterrupted time. Sixty minutes of refactoring done in six-minute increments at various times during the day has close to the same impact as one 60-minute block of refactoring. Sixty minutes of uninterrupted time is barely enough to even start to code, though, and six-minute blocks are almost worthless for development.
It’s also worth taking developers’ moods into account. The simple truth is that you’re more productive at some times than at other times. Sometimes you can bang out hundreds of lines of code almost as fast as you can type, and other times it’s an effort to force your fingers to the keyboard. Sometimes you’re in the zone, completely focused on the task at hand. Other times you’re distracted by an aching tooth, an upcoming client meeting, and your weekend plans. Coding, design, and other complex tasks don’t work well when you’re distracted; but refactoring isn’t a complex task. It’s an easy task. Refactoring enables you to get something done and move forward, even when you’re operating at significantly reduced efficiency.
Perhaps most important, I find that when I am operating at less than peak efficiency, refactoring enables me to pick up speed and reach the zone. It’s a way to dip a toe into the shallow end of the pool and acclimatize to the temperature before plunging all the way in. Taking on a simple task such as refactoring allows me to mentally move into the zone to work on more challenging, larger problems.
Getting Things Done
Refactoring is not unique in this, by the way. There are a lot of productive tasks you can use to nudge yourself into the zone. Writing tests, measuring and improving code coverage, fixing known bugs, using static code analyzers, and even spellchecking can help you to be productive and get things done when you just aren’t in the mood to perform major tasks. The key is to not become blocked on any one task. Always have something else (ideally several something elses) ready to go at any time. Sometimes you just need to find the task that fits the time rather than finding the time to fit the task.
Refactoring is really a classic case of working smarter, not harder. Although that maxim can be a cliché ripe for Dilbert parody, it really does apply here.
This concludes Chapter 1. Chapter 2 commences tomorrow.
June 10th, 2008 at 3:55 pm
This sounds good, but I wonder if it’s actually true: >Sixty minutes of refactoring done in six-minute increments at various times during the day has close to the same impact as one 60-minute block of refactoring. I’m tempted to say it isn’t, because effective refactoring requires thinking about the structure of the code as it stands, and as it should be. This is hard, possibly harder than writing the code in the first place.
June 13th, 2008 at 2:54 am
What a load of poppycock. The biggest objection to refactoring, which isn’t even mentioned in the article, is that refactoring done on any non-trivial project/product also requires a non-trivial amount of retesting.
—
Simon
June 13th, 2008 at 9:30 am
Re: Simon
There are many kinds of refactorings that can be done on a non-trivial project without significant amounts of testing. For example, you can safely replace new Integer(5) with Integer.valueOf(5) almost without reguard, unless the Integer is being used as a lock and it needs to be a unique object. Synchronizing on Integers is not overly common and it is something that you are likely to be aware of when changing some source code.
It really depends on the complexity of the refactoring. Using eclipse to rename methods is pretty darn safe. If something could cause overshadowing or a hiccup, eclipse has decent warnings. Or how about getting rid of System.out.println and replacing it with a logging facility? You need to decide on what kind of message is being written out. It is tedious and there is no real way to automate this change over. Out of the 1,000s of changes I made in moving our code base over to log4j, I’m not aware of any bugs introduced even after more than a year of it being in production.
I have done non-trivial refactorings and yes it does take time to both implement and fix everything that you might have broken. And I agree this kind of refactoring isn’t something that you will do in your random spare time. But I have a feeling the author is getting at the simpler kinds of refactorings.
However, I generally agree that simple refactorings can be done in your down time. It makes maintenance much easier. And it improves your own programming by pounding into your head not to do x, y, or z. I’m a proponent of refactoring code, especially code that you are intimately familiar with.
June 13th, 2008 at 9:38 am
Simon,
This is only one part of the book. Testing is coming up in Chapter 2. 🙂