header-sample
Refactoring Rebuilding Software Development Legacy Applications
Dec 23rd, 2019 - Derek Harrington

Rebuild or Refactor Legacy Applications: A Case Study

What is code refactoring?

Before we dive into our argument, let’s clarify the definition of “code refactoring”. Code refactoring is defined as “the process of restructuring existing computer code—changing the factoring—without changing its external behavior.” Usually this can extend to improvements made to the design, structure and implementation while still maintaining the core functionality.

Today, we are going to look at one particular situation and evaluate the pros and cons of either rebuilding or refactoring an application.

A Case Study: Microsoft Project Pyramid

On October 5th, 1991, Microsoft released their version 5.0 Word program for Macintosh computers. M. Richard Schaut, a principal software designer of three decades, recalls the time in his company’s history:

The reviews were glowing. For the effort, we received the software equivalent of a Tony award: the Mac World Eddy. Even today, there are people who say that Word 5.0/5.1 comprise the best version of Word we’ve ever shipped.

Microsoft’s Word software was released to such aplomb, that it almost masked two vital flaws.

The first flaw: Mac Word users were given a great word processor, but it lacked a few features that its Windows counterpart possessed. Some Mac owners cried afoul.

The second flaw: WordPerfect was still better than Windows Word.

To address both concerns, Microsoft initiated a major undergoing. They called it “Pyramid”: Mac and Windows Word would be rewritten from the ground up.

Rebuilding presented a significant opportunity. The developers could knock out some persistent issues with their existing code bases, which had by then developed a layer of rust. More importantly, the Mac and Windows versions--which had distinct code bases, to that point--could now be combined, saving future time, investment, and ensuring parity across the two platforms.

In short, Pyramid seemed like a great idea.

But it was killed not long after it started.

When Rebuilding Doesn’t Always Make Sense

To understand why Pyramid had to die, and why it’s an example to the rest of us, imagine a car. It’s a good car, but it has a few issues. It’s got a lot of miles under its belt. The engine is sputtering. The brakes are worn to the point where they make an annoying squeaking sound every time they’re applied.

It’s tempting, in such a scenario, to use these problems as an excuse to replace the car. But do we really need to spend tens of thousands of dollars on a brand new vehicle, when a few hundred dollars for a mechanic would suffice?

Some code really does require wholesale replacing. If you’re dealing with a program that is simply beyond repair, then you have no choice but to rebuild from the starting line. And there’s the problem faced often by developers: taking on a project from the hands of someone or some company entirely unknown to you. Mac Word might have aged over time, but it was always the property of Microsoft engineers--their fingerprint was on the work, and they could retrace the logic of how they built the program over time. If you take on somebody else’s work, you may find their writing illegible, or fail to understand significant chunks of the code you’re supposed to be working with.

Even in such cases, though, there are consequences to completely rebuilding.

Joel Spolsky, a software developer and creator of Trello, has a theory: that rebuilding software is “the single worst strategic mistake that any software company can make.” In a blog post, he gives an example of a messy, two-page-long function. Typically, this kind of code would signal the need for a rebuild. But should it?

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 us wants to trade in that old, raggedy car for a shiny new one. But that’s a feeling, and sometimes feelings get in the way of reason. Spolsky’s point is that the very thing that makes code seem too-far-gone is often, in fact, what makes that code necessary to build on. All that ugliness keeps the machine moving. Even if it’s got a few hitches, it’s seen battle, and survived. By replacing the work of those before you, you’ll likely have to retread all the steps those developers went through--those steps that made the original code so messy in the first place. Small bugs will pop up along the way. The risk of major bugs arises.

If you’re working on a popular software product, there are both technical and political consequences to rebuilding. Without the ability to produce regular updates, customers won’t be able to experience all the work you’re doing behind the scenes, for the entire time it takes to rebuild. Plus, customers appreciate familiarity--after all, they’ve spent time learning how to navigate the software you’re now considering throwing in the trash. Publishing an entirely new product might upset some customers, and cause confusion for others.

Much of the time, a simple shape-up job is enough. Refactoring reduces the risk of major bugs, and generally takes less time and money and work hours to accomplish. If you’re working on a popular product, you can make regular releases as your development progresses.

Ultimately, by refactoring rather than rebuilding, you’re making a tacit acknowledgement: that those developers who came before you weren’t bad coders, they simply did what was necessary to build a working product. You can build off their hard work by improving, not erasing it.

When is refactoring an application not appropriate?

There are two conditions under which refactoring is the worse option of the two. First: if you calculate that it really would take more time and effort to refactor, rather than rebuild. Second, and even more importantly: if you find that changes to the existing code base have significant, unpredictable ripple effects throughout the rest of the program. Part of the issue with editing someone else’s work is that you don’t have them there with you, to explain how all the cogs were designed to move together. If you find yourself not understanding the program you’re working on, there’s no use trying to build on it, as you’ll likely only compound the problems it was designed to prevent.

When Microsoft made the decision to rebuild, it seemed like a great way to get a fresh start. They changed project managers, and reversed course. The new manager decided that it would simply take too much time and investment to rewrite both programs from scratch, when the problems they faced could be solved in other ways.

Instead of rebuilding, the new versions of Windows and Mac Word would be based off the existing Windows Word 2.0 code base. This allowed Microsoft to build off its already lauded product, rather than scrap it entirely, while also merging the two programs’ code bases.

The company saved years of time and investment. What was the result? The year they made the decision to refactor rather than rebuild, Word out-sold its primary competitor, WordPerfect. Half a decade later, it possessed a nearly 100% market share in the word processing business.

About Entrision

Entrision specializes in building web and mobile apps, and has recently been named a top web development company.