Refactoring the Wheel

jest on 2003-10-29T19:19:14

Perhaps a year ago, I wrote some programs to deal with running a library database. The application worked nicely, but the programs were terrible--huge chunks of repeated, unmaintainable code.

A number of months ago, I learned a lot more about OO Perl, and went through a big refactoring binge and stuffed lots of things in modules.

A smaller number of months ago, I learned even more about OO Perl, and fixed some of the infelicities of the code.

A few days ago, I greatly generalized the code, so I can use the same modules to handle other databases I work with. This refactoring pass went very smoothly, and I felt confident. In the process I realized that one big chunk of the code is still appallingly bad; I spent a huge amount of effort on this elaborate solution to a problem that could have been solved much more easily if I had just used some templating system. (I had set up complicated modules to generate and process forms in a particular way.) So now I realize I have to go through and refactor this entire chunk to use TT or something, which will be non-trivial due to the complexity of the existing code.

When I'm finished with this, I will be in exactly the same place as over a year ago. I mean, I'll be a better programmer, and know a lot more, but this code has been in production use the whole time and no one knows I've done anything at all.

I suppose this is a good thing. But I'd like to throw in something neat, that I couldn't have done a year ago, or something.

</meditation>


You're doing fine

jdavidb on 2003-10-29T20:38:38

When I'm finished with this, I will be in exactly the same place as over a year ago. I mean, I'll be a better programmer, and know a lot more, but this code has been in production use the whole time and no one knows I've done anything at all.

You've actually accomplished something great, then. The code will be much more maintainable. I'd see lines of code eliminated as a good metric of how much you've simplified the system.

Throwing code out is liberating. Gets rid of bugs, too.

I suppose this is a good thing. But I'd like to throw in something neat, that I couldn't have done a year ago, or something.

Bide your time. Programs rarely sit still. Eventually a feature request or bugfix will come in, and you'll get it done ten times faster than you would have on the old system.

Also, think how much better the next system you write will be, from this experience.

Re:You're doing fine

ziggy on 2003-10-29T20:49:22

You've actually accomplished something great, then. The code will be much more maintainable. I'd see lines of code eliminated as a good metric of how much you've simplified the system.
There's a scene in Revenge of the Nerds, where someone from Microsoft (I think it was Steve Ballmer) talks about what it was like working with IBM on OS/2.

The IBM developers were stodgy old mainframe types, who were very regimented, hierarchical and by-the-book. The developers Microsoft contributed to the project were young hackers who had a "shut up and show me the code" kind of attitude.

One of the bones of contention was about Microsoft doing "negative work". They'd take some bloated, buggy code IBM had written, and rewrite it in fewer lines. (KLOC was the only metric IBM had to use for their progress charts.)

Negative work, indeed. ;-)

Re:You're doing fine

Timbo on 2003-10-29T21:04:41

I think maybe you meant Triumph of the Nerds, an excellent PBS show by Robert X. Cringely, not Revenge of the Nerds, an '80s teen flick with little to recommend it.

Re:You're doing fine

trachtenberga on 2003-10-29T21:17:56

Except Ted McGinley!

On Refactoring

ziggy on 2003-10-29T20:44:00

Refactoring is a hard sell with a program that works and doesn't need to be updated. As programmers, we deal with writing code (and debugging it, of course), so our focus is on projects that need work. We tend to ignore projects that are "complete" and don't need additional labor.

Cringely picked up on this a few months back. When it comes to working bodies of code, going back and refactoring something stable is a waste of time. But Cringley's ideas of an army of helpful Refactoring Gnomes is specious, and his anti-refactoring bent is decidedly Microsoftian. Even Martin Fowler doesn't talk about going back and refactoring a finished product, nor does he advocate mythical Refactoring Gnomes to rewrite code that has been written and deployed.

Refactoring works best to clean up code under development. The next best use for refactoring is learning how to be a better programmer -- studying a project, finding inefficiencies (or hidden complexities) and removing them. The first kind of effort has direct benefits -- code becomes easier to develop over the development lifecycle, and bugs are easier to find and root out at the source (instead of festering in a bug queue). The second kind of effort is a long term proposition, and difficult to justify in the short term, unless you can put a monetary value on programmer education and training.

Bob Martin (sorry, no URL handy) once talked about why refactoring is important, even if you don't feel like you're making progress. Think of programming as a craft, where programmers are like chefs. If you don't clean up the kitchen at the end of a meal, cooking quickly becomes a chore. Before you start, you have to dig out the spatula and frying pan from the bottom of the dirty dish pile, clean them off (if you are lucky enough to have an empty sink), scrape off all of the crud from the stove, and so on. At some point, you really begin to think about just buying a new kitchen with a full kit because you waste so much time rooting around the mess of your current kitchen just to fry an egg. Here, refactoring just like cleaning up your workspace at the end of the day -- it's tedious, and it takes time, but it's important. Fail to do so, and there's no way in hell you can make beef wellington without making a major production out of it.

Finally, there's the issue of when code is "finished". Although you may not have made any user-visible progress in the last year, chances are pretty good that you've done some other beneficial work, like optimizing a query, or something. If you had implemented all of the required features a year ago with crufty code, and you will never need to add another feature ever again , then refactoring was probably a bad move for the bottom line. If, on the other hand, you will be writing other programs in the future, or you have some other work that needs to be done on your library search, then there is a net long-term benefit to what you did over the last year.

You are to be congratulated

jordan on 2003-10-29T22:56:08

If you did all that internals work and nobody noticed.

Usually, when I do major rewrites, bugs and problems inevitably turn up. It shows that you worked deliberately and carefully and tested well.

Congratulations!

And remember, it's the journey (becoming a better programmer) and not the destination (source code) that is all the fun.