Refactoring Isnt Overhead

Refactoring in code isn't overhead, any more than writing a first draft is overhead in writing a book. It's an inherent part of one of the best ways of producing good code, just as writing drafts is an inherent part of one of the best ways of producing a good book.

Just found this interesting parallel in Baetjer: SoftwareAndWriting.

NOTES


Your project is complete when it [is in ExtremeNormalForm?] includes all required functionality and the code quality meets standards. (I'm not going to define "meets standards" here, but it relates to the code being well-organized, robust, not excessively redundant, having the right number of comments, being easy to maintain.)

There is a spectrum of ways to get to this point. Two points in that spectrum are:

  1. Get solid requirements for the whole system; design the whole system, figuring out where all the classes go and what they do; code it; test it.

  2. Design and code functionality incrementally, as you need it; refactor when the functionality breaks the OnceAndOnlyOnce rule and other rules of good factoring; test continuously.

Requirements change

Code implemented to requirements that change is wasted in that (a) it has to be changed; (b) it gets in the way of maintenance up until that change.

Code built incrementally (a) doesn't get changed when requirements change before it got implemented; (b) doesn't get maintained because it isn't there.

When requirements change, incremental development comes out ahead because sometimes you didn't get around to doing it wrong.

Design is hard

Designs done on paper, in the context of all requirements, are hard to do and often even harder to implement. There is much detail ignored in the DesignPhase, so that often a comprehensive design isn't that good for actually implementing.

Building incrementally can give more rapid feedback on design quality, allowing less costly adjustments to the design.

Because design is hard, incremental development comes out ahead because you learn sooner, reducing the cost of correction.

Refactoring has code churn

Systems done with upfront design churn their code less and therefore there is less total coding done. Is this necessarily good?

Programmers using incremental development spend more time churning code than programmers working from upfront design. Is this necessarily bad?

Upfront design spends less time programming

Systems done with upfront design tend to have separate groups assigned to design and coding, tend to create and maintain more documents, tend to have higher communication overhead.

Systems done incrementally tend to be done with fewer people and the people they have tend to be able to spend more time actually producing the product.

-- RonJeffries


How does refactoring apply to test scripts?

-- CayteLindner

If you DoTheSimplestThingThatCouldPossiblyWork with each iteration, you will sometimes find that a later iteration requires something more flexible than what you've written. You need to introduce additional layers of abstraction. So you refactor -- doing things like adding new classes, and moving functionality into common base classes, making it polymorphic. You don't always lose code by doing this. And good UnitTests ensure that you don't break the code by moving it.

So the cost of "code churn" mentioned above is much lower than you might expect. And you have to weigh it against the risk and cost of long integration cycles that often occur at the end of non-iterative development projects. (Ever been to IntegrationHell?)

-- JeffGrigg


CategoryRefactoring


EditText of this page (last edited May 6, 2008) or FindPage with title or text search