My group just finished up a massive year-and-a-half-long rewrite of a major project. I've blogged about events during this project several times before, from a stupid bug and a plea for help to reminding my boss that junior developers are awesome to building the ultimate RestSharp client. But, as of two months ago, we're done with it! It's running in production, and 20k people use it every day.
So now, it's finally time to discuss the biggest mistake I made during this project. This mistake ground the project to a halt. It was a mistake that could have easily been avoided had I taken the appropriate time to research other options. I'm hoping that, by sharing this mistake, you dear readers will learn from it and be given enough warning to prevent this mistake from taking down your projects.
Swing and a Miss
At the beginning of this massive rewrite, it was my job as lead developer on the project to determine what all needed to be done. We were given an order saying "take this 18-year-old project and rewrite it using modern technology and methodology." True to that order, I immediately dove into the existing codebase and attempted to determine what all it comprised of. There were sections for a library of documents, sections for an employee lookup, sections for links to other tools in our ecosystem. I found all the sections, wrote up an estimate, got it approved by our business unit, and my team was off to the races.
But I missed one. I missed a section, and the panicked decisions that resulted from that miss nearly killed the project.
The section that I missed was not very visible. You could liken it to a land mine: concealed and explosive. It was only accessible to a few people, a few very important people, a few people who were responsible for millions of dollars in revenue to our company. You had to have very specific permissions to even see this part of the tool. I didn't, but I also didn't look in the code for this section. I have no explanation as to why I found all the other sections we needed and not this one; I just missed it.
And yet, even that was not the true mistake.
The Dreaded Rewrite-In-Place
Once I learned that a section was missing, we were already 6 months into this supposed 8-month project. We were then forced to extend the deadline. We didn't extend it nearly enough. So in short order we were running up against the second deadline, the already extended one, and by this time the business had rightly had enough of our crap. At this point, I made the true mistake. I knew the end users and the business wouldn't be pleased with how I'd handled this, and so I chose to do something that has haunted the project ever since, something which to this day we are still dealing with the consequences of.
I directed my team to do a rewrite-in-place.
"What's that?" you ask. A rewrite-in-place is a well-known term I just made up that says we should copy the code from the old application to the rewritten one, fix it as little as possible to work in the new architecture, and then call it good enough.
If your head just exploded from the sheer short-sighted stupidity of this, well, I can't really blame you. Here's a paper towel.
In my defense, given the impending deadlines, it was one of the few options that made sense. We didn't have time to do a true rewrite, because that would require understanding all of the code enough to make it better. The rewrite-in-place removed this requirement, changing what would needed to have been a deep dive into code none of us understood into a shallow copy-and-paste job. In one sense, I took something that would have taken ages and made it very quick to do. But there's always a cost.
The cost was that I incurred significant technical debt on my team. If you don't know what that term means, Wikipedia explains it pretty well:
"Technical debt (also known as design debt or code debt) is a concept in software development that reflects the implied cost of additional rework caused by choosing an easy solution now instead of using a better approach that would take longer."
I chose to do the quick and easy solution, the rewrite-in-place. In the process, I knowingly chose not to do the correct, more-time-consuming solution (which would be to understand the missing section's code and rewrite it properly). It is that second decision, the intentionally choosing not to do the correct solution, that created the technical debt. Merely choosing to do a quick-and-easy fix does not incur technical debt if you aren't aware of a better option.
Technical debts are like taxes: you WILL have to pay them, it's only a matter of time. At some point in the near future, my team will have to start paying down the tech debt that my direction to do the rewrite-in-place incurred. They will be writing code to fix this bad decision, my bad decision, for quite a while to come.
(Yes, the acronym for rewrite-in-place is very much intentional.)
Rewrites-in-place are NEVER a good option. They are sometimes a viable one, but only as a last resort. If you find yourself in the middle of a rewrite-in-place, stop and ask why. Then go to your boss (or lead, or coworker) and check to make sure that's what you should be doing. Point out to them that this kind of work is guaranteed, GUARANTEED, to invoke technical debt. Make them defend their decision! It is through this kind of self-reflection and open communication that good projects survive bad ideas.
Don't do what I did, if you can help it. Don't chose the quick-and-easy route when a better one exists. Avoid the rewrite-in-place, and the technical debt that inevitably comes with it! You'll regret it. It won't be now, but it will be soon, and your team will be the one that suffers through the rewrite of the rewrite, as mine will be doing shortly.