Lately I'm getting a fair amount of email from developers complainingthat proponents of agile methods are ruining their code. Refactoring isgenerally seen as the root of too much evil by these correspondents.
A team member sees code that can be improved so they furiouslyrewrite a function or a method, invariably breaking something else.Since programmers generally believe that all code written by otherpeople is crap, the refactoring frenzy can consume vast amounts of timeand inject tons of defects.
To refactor means we simplify the code without changing its externalbehavior. We're not adding functionality or fixing bugs; we'reimproving the maintainability, structure, or organization of the codeto make it simpler or clearer.
eXtreme Programmers refactor mercilessly (Refactor Mercilessly on WikiWikiWeb),cleaning the code up on a continual basis. Since XPers evolve theirprograms, refactoring is a critical step in ensuring the code'sintegrity. Today's brilliant idea might look pretty dumb tomorrow.
But “refactor mercilessly” doesn't mean changing everything all thetime. XPers believe that, in general, if the code works leave it alone (IfItIsWorkingDontChange on WikiWikiWeb).
I think XP's approach to refactoring is very wise. In his 1981 book Software Engineering Economics Barry Boehm demonstrated that most of our code is actually pretty decent, but defects cluster in a smallpercentage of the functions. He showed that these lousy routinesconsume four times more engineering effort than the better-behavedones.
That academic result matches my real-life experience: when there's afunction that everyone is afraid to edit, or that only Joe dares touchbecause it's so fragile, that routine needs to be fixed. We often tryto beat the thing into submission, but that's like Sisyphus rolling hisrock up the hill. That code must be refactored.
Boehm showed it actually saves money to identify these buggyfunctions and take action early.
But refactoring is guaranteed to break things if done incorrectly.The XP folks correctly link it to other practices. One of those istest. In XP one constructs tests before writing or in parallel withwriting the actual code. Those tests must be comprehensive, must runquickly, and must be automated. Change something and run the test toprove nothing broke. Extreme tests make refactoring safe.
Automated tests are tough to implement in an embedded system whensomeone must watch LCDs or press buttons. One option is to writesimulations of those devices, either from scratch or by using aframework (for example, Catsrunner).Another is to debug completely in a virtual environment (for example, Virtutech).
Refactoring is also always done in small steps. A big rewrite tendsto introduce many bugs. Clean something up, test it, and move on.
But refactoring without a rock-solid test platform invitescatastrophe.
So my advice is mixed. Measure bug rates and refactor routines thatrepeatedly cause problems–you'll save money. But if your tests areweak refactor warily. On some systems refactoring is a Bad Idea ingeneral, since regulatory requirements may mandate hugely expensivere-verifications of the product.
I think the real issue is testing. A great series of tests opens aworld of software development options and risk-taking. But today thetechnology available for testing embedded apps, and our discipline infocusing on test in the real or simulated world, lags that in the ITbusiness.
What's your view? Do you refactor mercilessly? If so, how do youensure the changes don't break something?
Jack G. Ganssle is a lecturer and consultant on embeddeddevelopment issues. He conducts seminars on embedded systems and helpscompanies with their embedded challenges. Contact him at . His website is .
I'd like to give my own definition of “Refactor”. Hey buddy, you should have done it the right way or the best way the first time… me included. I think “coding” is really a process of tweeking and tweeking until it all runs smoothly.
– Steve King
One of the best parts about refactoring are the tests that it introduces. Increased software testing using requirements testing cannot be a bad thing. If a program is important enough to require maintenance, refactoring and verification tests should be equally important. It only makes sense to use the best tools at our disposal.
– Andrew Dawes
Refactoring can fix a lot of real problems and alleviate the problem that poor code reduces your product development velocity. My favorite link was not referenced in the article, but has a lot of information about low-risk high-value refactorings and when to use them.
– Don Willey
That is so true. The promises of XP are so appealing. For me, however, automated testing is one of the biggest issues why I am having a hard time adopting XP. The tools are just not there yet to be able to do them effectively and efficiently in embedded software development. And, as we know, all of the XP practices are interdependent on each other. You break one or two rules and everything breaks down. Despite that though, I am still hopeful of agile methods as the next evolution in reliable embedded software development.
– Barry Sia
Sr. Software Engineer
Here, we develop prepayment electricity and gas meters. We use the Crystal Clear agile methodology, with 100% automated tests on our code, using a PC & Borland C++Builder.
We have memory read & write capability through a serial port, and so can trigger tasks and read results of the tests. Any buttons are pressed using a relay on a USB based I/O card. as is the application of mains electricity to the meter. The LCD is checked by reading the LCD RAM and re-interpreting the segment data (for another product we actually intercept the serial messages to an LCD module).
We find the value of 100% automated testing is enough to make any extra test hardware well worthwhile. I'd recommend it to anyone.
– Paul Hills