“An architect's most useful tools are an eraser at the drafting board and a wrecking bar at the site,” said Frank Lloyd Wright.
eXtreme Programming (XP) advocates a similar philosophy: refactor relentlessly. If the code can be improved, it must be improved. Ugliness is unacceptable. Elegance über alles.
Unfortunately, the definition of refactoring has been obscured by hearsay and casual use by folks who haven't read the original papers (for a good treatise on refactoring, see the c2 Wiki. Some use it to mean iterative evolution: changing the code to add new functions. Others see it as bug-fixing. Neither is accurate.
Refactoring is simplifying the code without changing its external behavior . Its purpose isn't to add functionality or fix bugs; rather, we refactor to improve the understandability (and hence maintainability) and/or structure of the code.
XPers make the interesting point that code duplication is one clear indication refactoring is needed. I go a bit further, arguing that wise developers count bugs and recode functions that have high error rates. That might involve refactoring (usually an incremental approach) or tossing bad routines and recoding from scratch.
Refactoring is not a new concept. In his 1981 book Software Engineering Economics, Barry Boehm shows that a little bit of the code is responsible for most of the problems. He demonstrates that a lousy routine eats four times more development effort than any other function. When we're afraid to modify even a comment, when the slightest change breaks a function, when the thought of any edit gives us the sweats, that's a clear indication the code is no good and should be rewritten. The goal isn't to add features or fix bugs; it's to make the function maintainable.
The alternative is to try and beat cruddy code into submission, a never-ending battle as the each “improvement” leaves the software an even more convoluted mess. The cheapest way to build great software is to refactor bad code, early.
The boss will freak if he hears you're tossing or restructuring working code. An old IBM story is illustrative: an engineer made a million dollar mistake, back when a million dollars was a lot of money. He was summoned to the office of President Tom Watson. Quaking in fear the engineer blurted: “I guess you'll be asking for my resignation.” “Resignation,” replied Watson incredulously, “I just put a million dollars into your education!”
Making a mess of a function is also an important educational experience. We may have screwed up, but have learned a lot about what should have been done. Use the experience we've just gained and refactor the mess.
What's your take? Do you refactor at all or accept anything that more or less works? Or do you embrace XP's idea of refactoring everything that can be improved in any way?
Jack G. Ganssle is a lecturer and consultant on embedded development issues. He conducts seminars on embedded systems and helps companies with their embedded challenges. Contact him at . His website is .
Remember that Kent Beck, Ward Cunningham, and most of the other theorists of the XPworld started out using Smalltalk. Every time you finish writing a method, you say “accept” and that *one*method gets compiled.
You just don't count the number of compiles if you have incremental compilation and live in a system inwhich there is no distinction between the development environment, the compiler, the debugger, and thetarget environment. With no “edit-compile-debug” cycle, test-first is a *lot* more comfortable.
I work in both worlds: I develop for bigger (but often embedded) systems using Smalltalk (including onesthat are safety-critical), and I also develop for 8-bit micros using C and sometimes assembly language.
I find that my attitude towards refactoring, at least, is the same (though the rhythm is different) in bothenvironments.
However, I also find that I don't generally do test first development in C (though I do develop in smallincrements with tests at every increment).
I do think, though, that tests themselves need to be tested. I am a believer in using code coverageanalysis, and feel that test suites should be verified for coverage (not that they'll ever reach 100% giventhe number of states possible in a typical system).
I do think that testing is often under-done (or done haphazardly) in the embedded world, though. How oftendo you see a good test suite, or people spending the money required to make an accurate hardware simulatorfor testing?
– Ned Konz
Refactoring is an appealing idea, and believe me, there are pieces of code I'vewritten that I would love to redo, but the client will indeed freak if I start charging hours to fix codethat already works. Refactoring is one of those practices that reaps benefits in the long run, but in theworld of small companies with limited budgets and compressed schedules, there is no long run.
– Allen Moore
I have never formally used XP but had many gratifying work experiences when Iapplied some of its tenets like paired programming and design-for-test. I also noticed a strong correlationbetween my work satisfaction and being allowed to refactor bad designs. The danger to clueless managers isthat if they unwittingly let their people fix such messes once, it becomes a lot more difficult to denythem in the future (and maintain the cover-up of past blunders!)
– Marc Vincent
I've not been quick to adopt refactoring, but when you're put on a project where you see some very questionablecoding, it's hard to resist.
Alas, you don't want to alienate the original developers, and management just doesn't see the value in changing “working code”(as long as you don't count all the hidden bugs), so you change what you can, and tread softly. You end up with another costly,barely working product that gets shipped, and hope you don't have to maintain it.
I think the real problem is the “sample of one”, where a project manager only knows how things have gone, not how they mighthave been had there been code reviews and refactoring. There's no time for that, we're too busy fixing bugs!
Without any effort for lessons learned, every project becomes another “sample of one”. Short of project managers reading up onsoftware development and learning from historical projects, I don't see how that can change.
– Robert Weber
You know, I always get a kick out of these 'movements' in software engineering. I've can see it as a bunch of guys (or ladys)sitting around trying to come up with terms to explain how we've always done things (given enough time). Of course we”refractor”. It's called 'learning from experience'. If you make Chili, and it's too hot, what do you do? Well, unlessyou're a descendant of my black lab, you'll make it less hot the next time. If you go out with your buddies and you have alittle too much fun and wake up with a hang-over, what do you do? Well, some things we never learn. But what refractoring isbasically saying is that after you've written something, used it a little, seen what it does, you might actually understand howit can work better. Well, assuming that half the things we do in life, we do better then we expect, and half the things we doin life, we do a little worse then expected, we'll be unhappy with 50% of everything we've ever done. Even if we'reexceptionally gifted and brilliant programmers (as we all are), we always learn and we can always do better. In fact, ifyou've completed a project, and look back on it without finding anything you could of done better, well, you're eitherincredibly arrogant, or you're missing insight into the art of programming. Refractoring, is nothing more then indulging yourdesires to remove the stink. A wise program manager will understand the need to perform some reengineering after initialdevelopment is done. When was the last time you wrote an article and didn't take some time to go back over it to 'fine-tune'it. Oh, but now we call it 'extreme-programming', or 'refractoring'.
The danger is when people look at these new-age terms and believe that it justifies sloppy engineering. “I don't need to dodesign because I'm going to 'refractor' when I'm done.”, or similar mantras from 'extreme programmers'.
Thanks again for your contributions,
– Rich Schmitt
I am quite bothered by the word “refactoring.” It is the title of a book by Martin Fowler, but he did notinvestigate the etymology of the word while writing the book (http://martinfowler.com/bliki/EtymologyOfRefactoring.html). Byasking around later, he was able to discover the origins of “refactoring”:”The one definite answer I got was from Bill Opdyke, who did the first thesis on refactoring. He remembered a conversationduring a walk with Ralph Johnson. They were discussing the notion of Software Factory, which was then in vogue. They surmisedthat since software development was more like design than like manufacturing, it would be better to call it a SoftwareRefactory.”
So the story all starts with the formerly fashionable term “software factory.” The prefix “re-“, normally used with verbs andverb derivatives, is added to the noun “factory.” Later the pseudo-word “refactory” is transformed into the verb “refactoring.” The situation is exacerbated by the fact that factoring is already a well defined verb in the English language, but”refactoring” is not equivalent to “factoring again.”
It is no surprise that such a word is a source of confusion. A word, created by a series of decisions that disregardedprecision and simplicity, that now proves difficult to use. This is exactly the type of behavior that the proponents of”refactoring” claim to help us overcome in software design. I hope they will do the same for software-engineering literatureand “refactor” the word “refactor” out of existence.
– Derek Guerdon
It's interesting to manage both SW and HW engineers. while the SW engineers read books on “refactoring” and contemplate”coding it all over again”, the HW engineers strive to do the job right the first time. i work in the telecom industry, and itis not unusual for our product to have a service lifespan of 7-12 years. it would appear that the HW engineers plan for that,test for that, and ship for that; whereas the SW engineers approach the problem as “well, if this doesn't work out we'll justrelease a patch; and if it sorta works but is ugly, we'll 'refactor' it (and introduce yet more bugs).” the HW devs work deepinto the night to instrument their designs with abandon, yet ask a SW person where their bottlenecks are and you are met with ablank stare.
before all of you SW types jump on me as a HW-centric propeller head, let me say this: i *am* a SW developer, in that i doembedded firmware. i bridge the HW and the application SW. and from my experience the approaches to the work in front of themare markedly different between the HW devs and the SW devs.
yes, i know that there are SW patches for HW problems. but more often the case is that the SW “coders” and “programmers”forgot that they were supposed to be acting (and are getting paid to act) like engineers. hence, instead of understanding thetechnical problems they were off somewhere reading books on, yep — you guessed it — refactoring…
what is the point of “computer science” if one of the basic approaches is to do it all over again? here's a crazy idea: buildthe foundation correctly before you put the house on.
rob pike was right…http://www.cs.bell-labs.com/who/rob/utah2000.pdf
ps – at this point the SW folks are going to lament “but the requirements…” and “with so few HW CPU cycles…” and “theschedule…”
answer: buck up.
– bob barker