Joel Spolsky, co-founder of Fog Creek Software (of Trello fame) and former CEO of Stack Overflow, once famously said, “The single worst strategic mistake that any software company can make: Rewrite the code from scratch.”
On the other hand, there’s no doubt that legacy code can be very costly: It might take new developers weeks to understand enough to make their first commit on a legacy code base or legacy code might be so complex and coupled that even a simple bug fix takes a long time.
Let’s take a look at refactoring, rewriting and how to decide between the two when upgrading your software applications.
Big rewrites have a poor track record in software development, but that doesn’t mean that it’s never a good idea. Share on XWhat is Refactoring? What does refactor mean?
Refactoring is the process of restructuring existing code without modifying its external behavior. This can be done for a number of reasons, such as improving performance or making the code easier to maintain. Sometimes, refactoring is also referred to as code cleanup.
Refactoring is an important part of software development and can help make code more efficient and easier to work with. It can also help improve the overall quality of a program. When done properly, refactoring can make code more reliable and easier to understand.
For example, a simple adjustment to a piece of object-relational-mapping (ORM) code might eliminate an N+1 SQL query and dramatically improve performance. It’s a typical part of the Agile development process designed to ensure high-quality, maintainable code.
Before:
# Controller
@article = Article.order(published_at: :desc)
# View
@articles.each do |article|
Title: <%= article.title %>
Author: <%= article.author.name %>
end
After:
# Controller
@article = Article.includes(:authors)
# View
@articles.each do |article|
Title: <%= article.title %>
Author: <%= article.author.name %>
end
Example of a refactor in Ruby on Rails to improve performance.
There are three reasons to refactor code:
- Maintainability: Refactoring makes code easier to maintain by decoupling components and reducing complexity that arises as a natural byproduct of any new code.
- Extensibility: Decoupling code through refactoring also makes the code more extensible, which can dramatically speed up feature development.
- Performance: Refactoring can improve performance by taking advantage of newly released or mistakenly omitted language or framework features.
The problem is that refactoring can be a challenge with legacy code bases. In some cases, refactoring code can take more effort than simply rewriting the code. Refactoring efforts may also be subject to language or framework limitations to performance, and in some cases, you may run into limits that you cannot possibly surpass by refactoring existing code.
What It Means to Rewrite - Pros and Cons of Rewriting an Application
To rewrite an app involves scrapping or substantially rebuilding an existing code base. For example, a software project using an unmaintained framework may be rewritten using a modern framework to address security vulnerabilities. Another common example would be rewriting an application using a language that’s inherently more scalable or performant.
There are a few reasons to rewrite:
- Legacy: Legacy code might be a poorly documented black box that makes it impossible to refactor without excessive time and effort.
- Security: Software that relies on unmaintained languages, frameworks or other dependencies may need to be rewritten for security purposes.
- Performance: Developers may run into language limitations that limit performance, such as concurrency limitations for real-time web apps.
The problem is that rewrites tend to have a much higher cost than refactoring and have a poor track record of success. In addition to deleting knowledge accrued over years, rewrites take time away that could be spent developing new features. These drawbacks could have very high opportunity costs from a business standpoint.
How to Make the Right Decision
The decision to refactor or rewrite is difficult because of inherent differences between stakeholders and software developers. At their core, most developers are architects that would much rather start fresh and build something grand. On the other hand, stakeholders tend to be more interested in developing new features and limiting costs.
There are a couple key questions to ask:
- Why do you want to rewrite or refactor the application? Are there real security and performance issues at stake that impact business use cases?
- What are the costs and benefits of each approach? Aside from the financial costs of a rewrite, how much does legacy code affect things like developer morale?
- How does the existing code base impact things like infrastructure complexity and costs? Could you save money on the backend from a rewrite?
If you’re debating between a refactor or rewrite, it might help to have an outsider’s opinion. At Sharkbyte, we can help assess your project and determine the best path forward while taking into account both developer and stakeholder considerations. Our team augmentation services can even help provide senior-level engineering expertise to execute either option.
Contact us today to schedule a free consultation.
Best Practices to Keep in Mind
- Always Be Refactoring: Refactoring should be a built-in part of the development process in order to minimize technical debt and ensure high-quality, maintainable code.
- Minimize Your Tech Stack: Only use the dependencies that you need in order to avoid facing issues with unmaintained projects in the future that could trigger a rewrite.
- Go All-in on a Rewrite: Don’t try to rewrite an application by converting existing code into new code—design it the right way from scratch.
- Migrate Users Over Time: Don’t move every legacy user over to a new system at once. That way, you can ensure stability at scale and address any problems early on.
The Bottom Line
The decision to refactor or rewrite is surprisingly common. While many developers prefer to start with a clean slate, stakeholders would prefer to minimize costs and derisk the project with incremental refactoring. The right decision ultimately depends on the underlying reasons, costs, benefits and the long-term impact on productivity and morale, among other things.
If you’re struggling to arrive at the best decision, we can help you assess the benefits and costs from an objective standpoint. If you need help with either project, we can also provide both custom application development and team augmentation services to ensure success.
Contact us today to schedule a free consultation.