loading...
Cover image for The Rewrite vs Refactor Debate: 8 Things You Need to Know

The Rewrite vs Refactor Debate: 8 Things You Need to Know

bosepchuk profile image Blaine Osepchuk Updated on ・9 min read

So, if you're reading this it means you're involved in a software project that's a steaming mess and you want to explore your options. Don't be embarrassed. This is a safe place; we've all googled "rewrite vs refactor" at some point.

The problem is that our profession is long on opinions and short on evidence for what to do with troubled projects. And the opinions we have are all over the map. So, it's hard to know what you should believe.

In this post, I'm going simplify things for you and help you navigate the rewrite vs refactor debate.

Let's get started.

1. It's all opinions. None of the top results for "rewrite vs refactor" are peer reviewed research

It's easy to fall for a good story. But anecdotes are not the same as evidence.

blind people trying to describe an elephant by touch

Think about it: what do you really know about the expertise of the person who wrote whatever it is that you read? The bar for publishing a blog post online is extremely low. How would you feel if you learned the article you read was written by the worst programmer you ever met? How about someone with less than one year of experience? How about someone who has only worked on one system, ever?

And it works the other way too. Do you automatically believe what Martin Fowler says on refactoring because he's famous and wrote a book about it (also not peer reviewed by the way)? How about Robert C. Martin who wrote that "[rewriting] is probably the worst thing you could do"? That seems pretty dogmatic. No exceptions? Ever?

2. Rewrite vs refactor is a false dichotomy

Rewrite, refactor, or continue with business as usual are not your only choices. You have a whole spectrum of options.

Even within one system, the best solution for different parts of it might be different.

3. Rewrite and refactor are not precisely defined terms

You'll see this over and over again as you read blog posts about rewriting vs refactoring software. "Rewrite", "restructure", "redesign", "re-architect", "untangle", "port", etc. are all ill-defined terms. They mean what the author decides they mean. If you're lucky, the author will tell you what that is, but that's rare. So, one person's refactoring can and often is another person's rewriting.

This leads to unhelpful debates in the comments sections where people are arguing because they aren't even talking about the same thing.

4. Your project lives in a context

If you only focus on technical considerations you could reach a conclusion that is completely unacceptable to your larger context. Perhaps your employer has priorities, obligations, or plans you don't know about.

For example, your company might prefer a more predictable approach to improving your software, even if everyone agrees that a rewrite will probably be faster. They could have made secret promises to customers about future features of your software. They might be counting on cash from another project to keep the business out of bankruptcy and you can't do that project and a rewrite or refactor at the same time.

I know programmers generally hate politics but your decisions don't exist in a vacuum. Contemplating a rewrite or refactor of a non-trivial project is going to get people's attention and you can bet it's going to get political.

5. Size and complexity matter

It should go without saying that rewriting a short script that calls ImageMagick and resizes the images in a directory is COMPLETELY DIFFERENT than rewriting all the software in the F-22 Raptor. While this is an extreme example, even projects that are superficially similar might be very different on the inside and call for different approaches to keeping them viable.

6. How do you define success?

This is another problem with loosely defined terms. People write stuff like "we successfully rewrote our software from scratch in three months and it would have taken much longer to refactor it". What does that mean exactly? What defines success? 10% ROI? 15%? The project had a positive net present value before interest, depreciation, and taxes? Seriously, what? The details matter.

And let's not just accept the other part of that statement without some examination. How do they know that a refactor would have taken longer? The only way they could know for sure is if they did both the rewrite and the refactor, which I guarantee did not happen.

Another question: could that successful project just have traded one set of problems for another of equal or greater ugliness?

Finally, was the project a success for all stakeholders? I can imagine a scenario where the developers could see the project as a success because they got to dump some of their technical debt. But the business people might be on the verge nervous breakdowns because the market changed and their competitors stole the majority of the business's customers while the developers were busy completing their "successful" rewrite.

7. How do you define done?

When is the software ‘done'? Let's look at a "successful" rewrite and see if we can agree on when it is done.

Is it the day:

  • you deploy it?
  • it has exactly the same features as the existing software?
  • enough of the new defects are fixed that customers can use it without cursing the day you were born?
  • all the defects are fixed?
  • the money runs out and the customer is stuck with whatever you give them, even if it's buggier and has fewer features than the version you are replacing?

Any of those things could be considered "done", right? What's the chance that the author of the blog post you read is using the same definition of done as you?

8. So, how do you decide what to do?

Most people want to do a rewrite. It's very appealing to start from scratch. Whereas, people often see trying to improve the existing system as the long, hard, ugly path to better software. So, the first thing you need to do is determine if a rewrite is even feasible.

Start by acknowledging that a large software rewrite is risky. Many fail, some seriously injure the company, and a few kill the company outright. But technical debt and obsolescence can be just as dangerous in their own way.

Sometimes factors outside your control force you to do a rewrite. For example you might need to change the behavior of a system for which you only have a binary, and not the source code. Or the software is tightly coupled to ancient hardware that you cannot reliably keep in service.

Whatever the case, if you've reached a tipping point on technical debt or obsolescence, everything you do will be risky, including continuing with business as usual. There are no good choices at that point. That's why you should do everything in your power not to allow your project to get that bad.

Minimum requirements to consider a rewrite

Certain things need to be in place before you can even contemplate a rewrite. Max Kanat-Alexander has written about this in his book Code Simplicity.

...there are situations where a rewrite is acceptable. However, they are very rare. You should only rewrite if all of the following are true:

It's quite a long list so I'm going to paraphrase Max's words:

  • You have developed an accurate estimate that shows that rewriting the system will be a more efficient use of time than redesigning the existing system.
  • You have a tremendous amount of time to spend on creating a new system.
  • You are somehow a better designer than the designer of the original system.
  • You fully intend to design this new system in a series of simple steps and have users who can give you feedback at each step along the way.
  • You have the resources available to both maintain the existing system and design a new system at the same time.

But these are just the minimum requirements to consider a rewrite. The next section digs in a little deeper.

Things to think about before you propose a rewrite

Can you and your stakeholders agree on the answers to these questions?

And I have some questions of my own about rewrites

  • Rewriting from scratch requires different skills than maintaining and extending a system. What evidence do you have that your people can complete this kind of project successfully? When was the last time they did it? What assurances do you have that you won't end up with a new system with just as many problems as the old system?
  • The system you want to rewrite is complex, hard to understand, hard to change, is full of inconsistencies and defects, has low test coverage, and has low-quality documentation, if there's documentation at all. Correct? Would it be fair to say that nobody completely understands the existing system? If that's true, how are you going to figure out everything the existing system does and turn that into a set of explicit requirements for the new system *in a reasonable amount of time*? Can you even estimate with a reasonable degree of accuracy how many requirements there will be for the new system? Probably not. So, how can you estimate the implementation effort for the rewrite?
  • Doesn't a big rewrite from scratch look a lot like a giant waterfall project where the requirements are scattered haphazardly in the source code of the existing project? Didn't we adopt agile and incremental feature delivery because waterfall and big up-front design was too risky?
  • I've argued against simultaneous feature development because of the increased costs associated with delayed feature release. Isn't a rewrite an extreme version of this?
  • Are you sure a rewrite is the best use of your people's time? There's a whole continuum of options between tiny refactorings and rewriting from scratch, with the rewrite being the most risky and most extreme. Is it possible that a less extreme plan might be more desirable?

You've answered all the preceding questions and still want to do a rewrite. What now?

A complete rewrite of a non-trivial system is a major undertaking that carries significant risks. But if you decide to go ahead with a rewrite, it's best to do it with your eyes open because you might be proposing the software world's equivalent of Jamaica attempting to conquer Russia. Via the north pole! In winter!

overwhelmed by the scale of the task

Success is not automatically impossible, but it won't be easy. And without proper planning, the support of your entire organization, and adequate resources, you might be volunteering yourself and your team for a death march. So, make sure you have a plan that will work before you commit your team to a rewrite.

Takeaways

The rewrite vs refactor debate is largely the result of the following factors:

  • lack of evidence backed by quality research
  • lack of standardized engineering methods in software development
  • the desire of programmers to avoid bad code
  • software developers believe (often naively) that they can produce a better system if they start from scratch
  • poorly defined terms
  • oversimplifications of complexity and acceptance of anecdotes as evidence
  • a highly visible record of failed rewrites
  • and a narrow focus on technical concerns

While appealing, rewriting a non-trivial system from scratch is risky. Many people advise against it in all but the most dire of circumstances.

But in some cases, a rewrite is your best or only option (example). In those cases, you need a good plan to maximize your chances of achieving a successful outcome.

So, now that we've identified and cleared up some of these issues, you should be in a position to think logically about what you read, how well it applies to your situation, and see the rewrite vs refactor debate for what it really is.

Good luck with your decision.

Agree or disagree? I'd love to hear your thoughts in the comments section.

Enjoy this post? Please "like" it below.

Additional resources:

Posted on Mar 26 '18 by:

bosepchuk profile

Blaine Osepchuk

@bosepchuk

I'm a small business programmer. I love solving tough problems with Python and PHP. If you like what you're seeing, you should probably follow me here on dev.to and then checkout my blog.

Discussion

markdown guide
 

I'm somewhat unique in that I first did a academic career on how to build software and then a, by now, 15 years follow up career actually building software. Back in the day, I wrote an article on what I then called design erosion. And a lot of what I academically pondered there (I wouldn't go as to claim any hard evidence), has sort of been validated in what I've seen in various projects since and backed up by what others have been saying lately.

It's very simple, there are no absolutes in software engineering. The word engineering apart, it is mostly a soft science. That being said, that doesn't mean that you can't be rigorous in how you conduct your business. There are other soft sciences with lots of good practices on how to do things. Economics for example.

Some things I found obvious 15 years ago are that the need to re-visit previously created software design becomes inevitable because whatever assumptions held true when you designed are extremely likely to change over time, thus making whatever was once the perfect design less than optimal. Patching it up erodes the design; these days we call it technical debt. Happens to all software. You can't prevent it.

If you bought into lean software engineering in any way, I highly recommend you check out the awesome work of Don Reinertsen on Lean 2.0: youtube.com/watch?v=L6v6W7jkwok&t=5s

He makes an awesome case for actually a lot of decisions in software engineering being very easy to quantify and has quite a bit to say about things like refactoring as well. The key problem is not that it is hard but that we simply assume it is. Also, there is no need to be perfect with your quantification, because it is pretty easy to out perform our gut feelings by magnitudes (hint, they are mostly wrong and highly inconsistent across teams).

There's a big risk for companies to get stuck patching up existing software for negligible improvements in revenue, or even just protecting already decreasing revenues, when a more wise investment would maybe be trying to figure out what customers really need next and building that. Doing nothing has a risk as well: you'll be left with an out of date completely worthless software stack that is impossible to adapt to new requirements. This kills companies all the time. For reference, just look at the fortune 500 of 20 years ago and check who is still around. Pretty brutal.

So, if you are faced with a software project that is difficult to maintain you have a problem. Step 0 is figuring out the impact of the problem. Is it slowing you down shipping stuff that customers would pay for? If yes, quantify & do the math: that's your lost revenue. Put a ballpark number on it. You have your per head cost and other cost on one side per time unit and you have the potential revenue delta that you are missing out on every month you are not shipping. Now do the math on how much a big refactoring round will slow you down: months not shipping x cost + lost revenue. Finally, do the math on patching up your existing software to get the revenue ASAP. It won't be pretty but if it gets you money in the bank next month, you can't just dismiss it as an option. On the other hand, does it stop there or does it just set you up for being even less competitive in a few months.

 

Thanks for writing such a thorough reply; I think your ideas complement my post nicely.

I agree with so much of what you wrote.

I like the part about software engineering being a soft science. I think Greg Wilson said something similar that I'll paraphrase is "What we do isn't really computer science. It's more like computer strong opinions."

I don't think there's a particular reason we couldn't approach what we do more like an strong engineering discipline. It's just that we work in a young profession full of cowboys--we'll get there eventually.

I'm a huge Reinertsen fan. I've written about his ideas a few times:

Even after writing three long blog posts on his book: The Principles of Product Development Flow, I've only covered the first couple of chapters. (Great book for those who are interested).

I think you're right on the money with your prescription. I'm not sure why more people aren't doing the math to figure this stuff out. Are software developers genetically programmed to avoid any kind of accounting? Just a theory.

Cheers.

 

Mostly just demographics, Joel Spolsky has some nice numbers on how the demographics are such that the amount of software engineers has been doubling every five years since the sixties. Which, in my age group means I'm out numbered by 24 by younger people, most of which have been active for less than 8 years. Explains a lot about people reinventing wheels.

That and a lot of Academic computer scientists never really figured out that there is more to building software than mathematics.

Another point somebody made recently that stuck with me is that in lots of professions it is common for managers to be practitioners themselves but somehow that is less true in software teams. Kind of odd if you think about it that key decisions in big companies that specialize in making software might be taken by somebody with essentially no direct experience building software; no clue about what is reasonable in terms of quality, technical realization, etc.

A pattern I see a lot in our industry is people with an MBA or some other non technical degree getting the product owner role, which in most companies means they call the shots on a lot of details related to when and what to ship. MBAs don't run armies, don't direct/produce movies, they don't get to head a team of chefs in any decent restaurant. Etc. So, what is so different about making software that it requires oversight by non technical people?

Good points. Robert Martin has said similar things about the relationship between the growth in the number of programmers and what that means for our demographics.

I've only ever worked in small companies so I can't speak to the truth of how they tend to staff the product owner role. But what you're saying makes intuitive sense to me. Stereotypical programmer thinking is not well aligned with stereotypical business thinking. Putting an MBA in to middle might help the business types sleep well at night knowing someone like them is in charge.

The thing that might be different is that not a lot of programmers want to be business types because the money is so good in programming and many/most programmers love to code. I've read that is not uncommon for the senior devs to make more money than their bosses. So, in other industries, moving to management is a way to advance your career and make more money. But in programming it means learning about business, getting involved in politics, and watching your extremely valuable programming skills deteriorate, while you supervise people doing the work you actually love. And potentially making less money.

It was indeed uncle Bob that wrote about this blog.cleancoder.com/uncle-bob/2014.... Must have confused the two. Anyway, fun statistics.

Regarding senior devs, I know a few (myself included) that are more or less self propelled. I tend to think of managers more like customers than leadership these days.