Topic: refactoring

Refactoring versus Rewriting

Refactoring versus Rewriting
I started my first real Agile software development project in 1999. I'd been doing more traditional software development before then all the way back to 1980. I won't bore you with the details of those earlier projects, but my feeling was that there had to be a better way of developing software that didn't involve a senior technologist (me) telling a whole bunch of junior technologists what to do. It turns out I was right. :-)
But almost from the start I got pushback from other people in the development organizations I worked in that Agile development was horribly wasteful. They pointed to Test Driven Development ("all those tests more than double your effort"), pair programming ("two developers doing the work of one?"), and refactoring ("you're rewriting the software every time at enormous cost"). Of course all of these objections were borne out of a misunderstanding of Agile development, but of how their own software development processes actually worked.
The issue of refactoring was particularly mysterious to my colleagues. If you took the time and designed software properly up front, you don't have to do expensive rewrites. Of course anyone who has ever maintained code knows that this isn't true. All code, regardless of how it is developed, changes over time for bug fixes and to meet the needs of new requirements. If you aren't thoughtful about how you change your software, you can easily end up with a big mess.
If you are thoughtful about how you change your software and think about the sorts of "code smells" that crop up in your code over time, you end up making more fundamental changes, rather than adding a method here or a instance variable there. You might see that two methods are always called in conjunction and decide they should be folded into one method (a design win), or you may have extended your design and ended up with two parallel hierarchies of classes. You break the Go4 glass and pull out the Bridge Pattern to solve that burgeoning design problem. Through constant refactoring (or rewriting, take your pick) you avoid painting yourself into a corner as your requirements change.
The fact is that good developers are constantly redesigning and rewriting their code. Those same developers will tell you that the longer you leave problems before refactoring, the bigger and more expensive they become, until you might be better off just scrapping the system and rewriting from scratch.
Agile development takes this normal refactoring to it's logical extreme. Rather than doing a big design up front and then doing a series of expensive changes when they are inevitably found to be wrong, Agile teams accept that their design will be imperfect and then build comparatively inexpensive refactoring into every iteration. It may seem counterintuitive, but all that refactoring results in code that is cheaper to develop, easier to maintain (because it's easier to understand, change and debug).
Among professional writers the golden rule is that the key to all good writing is rewriting. The same is certainly true of software.

I started my first real Agile software development project in 1999. I'd been doing more traditional software development before then all the way back to 1980. I won't bore you with the details of those earlier projects, but my feeling was that there had to be a better way of developing software that didn't involve a senior technologist (me) telling a whole bunch of junior technologists what to do. It turns out I was right. :-)

But almost from the start I got pushback from other people in the development organizations I worked in that Agile development was horribly wasteful. They pointed to Test Driven Development ("all those tests more than double your effort"), pair programming ("two developers doing the work of one?"), and refactoring ("you're rewriting the software every time at enormous cost"). Of course all of these objections were born not just out of a misunderstanding of Agile development, but a fundamental misunderstanding of how their own software development processes actually worked.

Continue reading »

Has Many has_many: A Refactoring Story

Lately I've been working on a revision of one of my first Pathfinder projects, an internal agile management tool. Along with adding and rearranging some features, I'm also taking the opportunity to modernize some of the Rails 1.2 era code up to new Rails 2.1 and 2.2 features.

Note 1: I don't always (or often) recommend a wholesale update of working code when updating features. But this was a large enough feature change that cleaning up the code is worth the effort.

Note 2: When the time comes for you to perform a major refactoring like this remember that your tests have all the institutional memory about how the application should work. What I actually did was create a new blank project, and copy test files one by one. For each file, I commented all the tests, then uncomment them one at a time, rearranging the test as needed to match the new data model. Sometimes I take the new code directly from the previous version, sometimes I rewrite using a newer or better idiom. This gives me the benefits of test-driven design in my big refactor, while still preserving all the functional specification in my tests. (This seems to work better on models than controller/views, I'll probably have a fuller report next week).

Continue reading »

Launch: Pathfinder Newsletter

    Get a monthly update on best practices for delivering successful software.

    Subscribe via email


    Subscribe via RSS      RSS icon

Topics

Search

WordPress

Comments about this site: info@pathf.com