I've been working with a customer on applying continuous design rather than rewriting a troubled system. This is an excerpt from a summary I recently sent him:
The goal of rewriting and continuous design is the same: to improve the design of the code, without changing functionality, so that future changes are faster and cheaper. (You might add functionality too, but let's ignore that for this discussion.) A rewrite starts with a blank slate, reimplements existing functionality, and then integrates with the remaining systems. Continuous design starts with existing code and incrementally improves it.
Effects of rewriting:
- Cost: Rewriting incurs a delay to delivering new features. The system being rewritten cannot be delivered until the rewrite is complete and it has been fully integrated.
- Benefit: A successful rewrite on a debt-ridden system will dramatically cut the cost of future development.
- Risk: Rewrites are high risk. They typically take longer than expected. Integration is where the most defects are found and integration occurs at the very end of the rewrite cycle, making it difficult to predict the true cost of a rewrite.
- Risk: Without a policy of continuous design, the rewritten system will gradually accumulate debt and eventually need to be rewritten again.
Effects of continuous design:
- Cost: Continuous design moderately increases the cost of delivering new features in debt-ridden systems.
- Benefit: Continuous design gradually decreases the cost of future development by eliminating debt one piece at a time.
- Benefit: Continuous design allows new features to continue to be delivered in a predictable manner without significant delay.
- Benefit: Continuous design focuses design efforts on most commonly-changed systems, possibly decreasing overall cost relative to a rewrite.
- Risk: Continuous design is low risk. The primary risk is that the team stops doing it.
- Risk: Continuous design's gradual improvement may not satisfy programmers looking for dramatic improvement.