Every line in your legacy code is there for a reason. Sometimes the reasons are bad, but often they're there because of some very valuable lesson you learned from a customer, a mistake you made that your competitor is also likely to eventually make. Throwing away your legacy code means that it's likely you'll make the same mistake again.
I know this probably means that I don't unit test right. It also obviously means I don't code right, because I have bugs. The point is, these are facts of (real) life, and to be successful you have to manage the reality. Often this means that the best course of action is to stick with the legacy code.
What legacy code does is inhibit your ability to make the fundamental changes you need to implement in order to stay competitive. And I'm not saying throw you code out every other week. And I'm not saying every attempt to rewrite your product should replace what you already have. But the for all the costs associated with re-writing your product, they pale into insignificance when compared to being put out of business.
But perhaps we can agree, then: rewriting code is a business decision, driven by the business needs of the company. Premature rewriting is just another form of premature optimization, and can get you in trouble by putting your resources in the wrong places. But when you have a tangible threat- when you are unable to adapt to accommodate needs that you are convinced are on your horizon, then you should do it.
I'm not saying you should never rewrite a system from scratch. But I do think it's extremely costly to do so, and that it's extremely difficult to predict when you'll be driven out of business if you don't. So I don't think it's usually justifiable.
I'd be very interested if someone could supply an example of a company that was put out of business because they failed to re-write their product.
There's always the possibility that your existing code doesn't suck, and was designed to be flexible for changes.
Ideally, you've done a good job and can rewrite small pieces of your system iteratively as needed, rather than having to chuck the whole thing.
Also, code that might look crap and seem to do weird stuff often handles intricate edge cases. But due to the lack of comments, it's not obvious what's going on.
I've been involved in several component refactorings when as a team we've gone "look how complicated the old code is, we can make it much simpler".
When we've re-written it and then tested it with actual production use cases, it then becomes obvious why the code was so convoluted previously. So time was wasted, but at least there are comments now (and in those cases, the code's slightly better).
Because that's exactly what someone else is going to do. The company that makes the product that competes with yours is unlikely to have picked your product at random and simply decided to compete against it on a whim. There's a good chance they've been using your product and have become so frustrated with it's shortcomings that they've had a crack a building there own version. They've been on your support forums that detail every bug and bad descision, they've read the blog post detailing exactly what is wrong with your features and how they could be done better. They've stared at their screen in a full on rage wondering why the hell your product doesn't do things in a way that makes sense. They have their own experience and they are not afraid to use it.
There could be one, tens or hundreds of people who decide to do this. Many will fail, but if one succeeds then you have a serious problem. The continued success of your product can no longer rely on it's features unless you're prepared to make some fundamental changes. Only now you have a deadline, whereas before you could have worked at your own pace.
You're right when you say your legacy code is your greatest asset. It's proof of what is a good idea and what is a bad idea. But that doesn't mean you should keep it around any longer than you have to.
Ideally, yes! Realistically, there's always some hairy, gnarly wisdom "baked into" the code.
The definitive article is Joel Sposky's article on the perils of writing from scratch. If you only want to read a few paragraphs:
"Back to that two page function. Yes, I know, it's just a simple function to display a window, but it has grown little hairs and stuff on it and nobody knows why. Well, I'll tell you why: those are bug fixes. One of them fixes that bug that Nancy had when she tried to install the thing on a computer that didn't have Internet Explorer. Another one fixes that bug that occurs in low memory conditions. Another one fixes that bug that occurred when the file is on a floppy disk and the user yanks out the disk in the middle. That LoadLibrary call is ugly but it makes the code work on old versions of Windows 95.
Each of these bugs took weeks of real-world usage before they were found. The programmer might have spent a couple of days reproducing the bug in the lab and fixing it. If it's like a lot of bugs, the fix might be one line of code, or it might even be a couple of characters, but a lot of work and time went into those two characters.
When you throw away code and start from scratch, you are throwing away all that knowledge. All those collected bug fixes. Years of programming work."
http://www.joelonsoftware.com/articles/fog0000000069.html
Ideally, yeah, you take that wisdom with you to the new project but realistically (even if you've followed great documentation practices, etc, for all of those hairy kludges) the rewrite-from-scratch is never as easy as one thinks.
Code becomes legacy pretty quickly, in my experience... Architectural decisions that were obvious before you had real customers rarely stand up to real usage.
The company that's "going to put you out of business" also doesn't currently have any working or revenue-generating code, and are unlikely to immediately understand the architectural challenges...
> I think you need to have a really good excuse not to completely rebuild your product from scratch every now and again
It pretty much just doesn't work in the real world; how's that for an excuse? As other people have said, you need to scaffold interfaces, and rebuild small parts. Any company that isn't continually reinvesting in making their codebase better will accumulate technical debt pretty fast; but the throw it away and start from scratch approach rarely works on big systems.
It is just someone else saying the same thing, or it's a real world example, or it's anecdotes-aren't-data.
"Things You Should Never Do" http://www.joelonsoftware.com/articles/fog0000000069.html
And I suppose we should also burn down factories and rebuild them every now and then.
The world of software is moving a lot faster than the physical world, so things can become outdated pretty quickly. Compare a 15 year old browser to a 15 year old factory.
Sure, it's nice to have the latest and greatest. But I don't think it gives you magical powers. You still need to do all the other stuff.
That, and the well-known problems with rewriting (the track record is notso hotso) mean that really, the onus for making a case to rewrite is on the rewriters.
If the market starts shifting to alloy wheels, and the reduced volume of sales for your steel wheels starts to affect the profitability of your factory, then maybe it makes sense to start looking at investing in updating your process to make steel wheels more cheaply at lower volume or to dump steel wheels entirely and start manufacturing alloys.
The Air Force Heavy Press Program made the rounds on the internet last year when Alcoa refurbished its 50,000 ton forging press in Cleveland [1]. It's been around since 1955, and it's almost unique in its capabilities within the USA. The idea that it should be replaced simply because it's old is, frankly, insane.
That's obviously a pretty extreme example, but the fundamental requirements for a metal lathe or end mill haven't changed in years. Yes, there are multi-axis CNC machines that can do vastly more operations before somebody has to change the setup on them than on a basic lathe or mill. If you aren't making something that requires a lot of steps, the basic lathe or mill might still viable.
Just because the rate of change in requirements over time is huge in software doesn't mean that it's true everywhere. If an old factory can continue to meet the requirements, it's probably hard to justify changing it just to be up to date.
EDIT: Forgot the link
[1] http://www.theatlantic.com/magazine/archive/2012/03/iron-gia... [1]
The company that's going to put you out of business is using an early version of their own legacy code.
It's not always obvious when you should attempt a rewrite from scratch. Having done a few refactorings, I've noticed one desirable trait in good code bases: If you can implement new logic easily in a few lines of code, it's probably a good design. But if you need to get out the surgeon's knife and write tons of new code every time you want to implement new logic, it might be fundamentally flawed enough to warrant a complete rewrite. A good design is adaptable and will allow you to be resilient against newcomers.
And furthermore, while the developers are rewriting the code, who is going to maintain the old code? The demands for new features and bug fixes aren't going to stop just because you've decided to rewrite the code.
Sure, we know have Firefox, but that's little consolation for the corporate entity that was Netscape.
Even assuming their newly-minted code is better (which others have disputed), what they don't have is loyal customers and brand recognition. If you're worth competing with, you do.
>> I think you need to have a really good excuse not to completely rebuild your product from scratch every now and again.
There could be many reasons. 1) That's expensive. 2) May introduce new bugs. 3) Interface changes may alienate existing customers. 4) Switching technologies may require new developers.
I wouldn't say "plan to rebuild from scratch periodically." I'd say "design your software to be flexible, watch your competitors, and iterate to ensure they don't leave you in the dust." If it becomes clear that you can't compete on features without a rewrite, then consider it.
I think you need to have a really good excuse not to completely rebuild your product from scratch every now and again. Because if you don't, someone else will.