views:

318

answers:

13

I've had my share of projects where the first thing I think is: "This code sucks; let's just rewrite it in framework X." Everybody feels the urge at some point. In fact, I think I've had the urge to rewrite pretty much every project I've ever been on.

However, it is accepted wisdom that a total rewrite is generally a bad idea. The question is: when do you look at a project and say: "OK, it's time to start over."

What sort of metrics or examples can you cite of where a rewrite was truly necessary? How bad does the code have to be? How old can a project get before there too much invested?

+10  A: 

I agree with Joel, you should only rewrite software as an absolute last resort.

http://www.joelonsoftware.com/articles/fog0000000069.html

The problem is that everyone thinks at some point in time, that it will be easier to rewrite something from scratch, when in reality it's not. That code which has had a number of updates over time, works in a certain way for a reason. There is normally a ton of little logic items which are done a certain way, because of an update or a bug fix etc. When you rewrite something, you have to mimic the behavior of each of those fixes, because they are important for one reason or another.

You'll hear a lot about the cost benefit analysis and when it is good to rewrite, the problem is that analysis is often wrong. If it takes a day to make a simple update, that is still a lot lot less than the potential months that it will probably take to analyze, design, code, test, and deploy the new version.

My old boss and I used to joke about this collection system program the business used. It was horrible, we hated maintaining it. One day he made the comment and he was absolutely right, "You know as much as we hate this system, it works. It does what it needs to." We both agreed that as much as it sucked, it did it's job, and ultimately we didn't rewrite it and saved the company 100s of thousands of dollars in building a new system. Thinking about that system, we never would have discovered all the little ins and outs of it did. The code was extremely difficult to understand, which is ultimately why we wanted to rewrite it in the first place.

Kevin
Primary counterexample: Netscape. The rewrite killed the company.
Joel
+1. True in many cases. Sometimes code is just poorly designed. I worked on a legacy file format where the original programmer didn't build in any way of extending the format. Then he extended it by using spare bits in certain fields to indicate an extra field had been appended, but again did not think about extensibility. It became impossible to add new info to the format, and "the last resort" hit: the format had to be redesigned at a cost of *weeks* of work converting old data. It should have been rewritten the first time extensions were added, which would have cost only a few hours effort.
Jason Williams
+6  A: 

Don't ever rewrite software. Refactor it throughout its entire lifetime.

John Saunders
+2  A: 

Typically, that point is when the Cost/Benefit Analysis shows that a total re-write is going to save more money than maintaining the old system.

Various factors can influence that Analysis though (like platforms no longer being supported, talented developers becoming hard to find, etc.).

If you do the Cost/Benefit Analysis the right way, you'll see that it never pays off to do a complete re-write. It'll only cost you time and headaches.

Justin Niessner
+6  A: 

Rewrite only when one of two things is true:

  1. The existing program doesn't work anyway, and is nowhere near working. (In other words, you inherited a "90% done" code base from your predecessors, not an actual product.)

  2. Step-by-step re-factoring is impossible because the new program needs a fundamentally different architecture, needs to run on a different technology stack or whatever.

In other words, the guideline (there are exceptions, but they are rare; you won't likely go badly wrong following this guideline) is, rewrite only when step-by-step re-factoring from a working product is not an option.

rwallace
+1  A: 

You may want to look into Iterative Development. At the outset I and probably almost every 'senior' developer cringe when we read about it. No forward planning? No thinking in abstracts and generalities? Just get it done? Doesn't that produce bad code? Not really. It will produce exactly what you need and as you come back and look at a function that was designed to do one thing you refactor it to do more, so forth and so forth.

This is effectively a constant rewrite but not reall. Those functions that never get refactored got done extremely quickly and do exactly what they're supposed to do. You also managed to implement then in a fraction of the time because you weren't thinking 10 steps ahead and made it generic.

You can start reading about it here: http://www.extremeprogramming.org/rules/iterative.html

To answer your question directly, stick to the principle of "If it aint broke don't fix it". Unless there's a need beyond "god that's ugly, I want to clean that up" don't rewrite what you've done.

Matt S
+1  A: 

If it's so bad that it needs a rewrite....call it a replacement. Add some new features, make it easier to maintain and use. Develop it with the latest technology available to your company.

The higher ups feel there's more value in replacing something that's barely working with something new & improved if it will improve workflow & productivity.

Make sure you don't call it a rewrite of crap code, because the people who wrote it may still be there.

Ed B
A: 

If it's already in a modern language, refactor instead of rewrite.

If I had a Cobol app and my mainframe was going away eventually, it's time to rewrite. If I found an old app written in FoxPro and we still need the fuctionality, rewrite.

But if it's in Java, no matter how bad it is, refactor one bit at a time. It'll honestly hurt less.

Dean J
+1  A: 

If the code meets absolutely zero of the requirements for the project, it might be a good time to rewrite it.

Zak
+1  A: 

One of the few situations where a rewrite may be necessary is when the language has become obsolete and there are no developers available to maintain it. In this case you may have to rewrite even good code that works perfectly.

And adding insult to injury, you can easily end up with something worse than you started with.

Charles
+1  A: 

A "rewrite" (or at least a serious bit of refactoring) is sometimes the best way forward when you realise a soluton is not scalable.

An example of this is a painting package I write back in the 1980's. It started off as a bit of fun working on a 16-colour bitmap. When it was 20kB of BASIC code, I thought "I ought to rewrite this to make it capable of handling 16 or 256 colour images". But it was "too much work". When it was 50kB it was clear it really needed to be rewritten, but it would just take too long. So I continued adding code that relied on it being a 16 colour image, till it reached the point where it was 140kB and utterly impractical to rewrite. I always regretted not biting the bullet when the rewrite was only a few hours work.

Another example: I worked on a vector art package which broadcast events around all objects in its scenegraph hierarchy. In the initial stages it had a few tens of objects and as my manager put it, "we can broadcast to over 10,000 objects per second", so the broadcasts continued. I suggested making interested objects subscribe to the events they needed to remove inefficiency, but there was "no need". 2 years (40 man years of effort) later, the program was grinding to a halt for 2-4 seconds at a time because the scenegraph contained more like 500 objects and the 2 broadcast events had risen to 40 or so.

This pattern has been repeated in several projects I have been involved in over the years - you spot a serious design flaw or technical debt and you defer fixing it because (a) it isn't a problem "yet", and (b) it would cost too much time to sort it out now. As time goes on, it becomes linearly more of a problem, but exponentially more expensive to fix. So although it needs fixing more and more, it is harder to justify the cost of fixing it.

In these cases, the technical debt or design flaw needs to be resolved as early as possible. It takes guts (if you're a manager) or persuasiveness (if you're an underling) to hold back your schedule for a week, but imagine having no recourse but to devote 2 months to the fix in a years time!

Of course, this argument does not apply to all cases. You need to evaluate the cost/benefit of any proposed fix, and consider the scalability of the problem - if the issue is a constant, then you can fix it for the same cost at any time in the future. If every new class you add to your system compounds the flaw, and you expect to add hundres of new classes, then go back and fix it now.

Jason Williams
A: 

One of the big propaganda items about programming is that is should be designed for code, and/or module based reuse. In other words, functionality should be broken apart into discreet re-usable parts. If you have code that is actually doing something, and that is meeting a requirement, the argument isn't then that the code needs to be rewritten, but rather it needs to be refactored to a state where it can be re-used.

This doesn't mean that you shouldn't throw away big chunks of code, and replace them.. In fact, the idea of refactoring tells us to do exactly that. However, the idea is also that while we are doing that, we should test and improve to ensure compatible behavior and increased reusability and modularization.

In fact, if you can take even one module that does something to fulfill a requirement, and rework it to be re-usable in "version 2", then by definition you haven't thrown out the code base and started over. And why would you want to if even in bad code, usually just a few tweaks are needed to clean it up into good code? Let alone the pearls of decent or even "good" code that exists in the project.

Zak
A: 

The very reason you are planning to rewrite it is because, the issues that you are seeing now was not forethought when it was written, there could be two reasons for this 1. It was not meant to do what it is doing now or 2. It was simply a mistake.

Do give it a very thorough thinking, if you are able to foresee all the things that it may require.

Only then rewrite it. But generally most well written and well managed code will only need refactoring.

Cheers, Pavan

PavanMysore
A: 
Norman Ramsey