Don’t Fear The Rewrite

by on April 8, 2013 8:44 am

Over the past dozen years, I’ve been involved in half a dozen engagements where my role was to lead an effort to rewrite a particular application. The applications were each very different, but there were quite a few similarities. This article gives my top ten tips for how to successfully rewrite an application.

Before jumping in, you should ask yourself why are application rewrites so common? In many cases, the application is working (at least, mostly) and it costs money to take existing, working functionality and write it all over again.

The main reason I hear is maintainability. Applications become too costly to maintain when you can answer “yes” to the following:

  • Is the application built on technology that requires outdated skills or tools?
  • Is the only way to know the application’s capabilities to “try it and see” or to get under the hood and look at the code?
  • Is there major concern that minor fixes may cause major breaks in unrelated parts of the application?
  • Is the application resistant to scalability?
  • Is it hard to add small enhancements, never mind making major improvements?

Any one of these reasons can be used to justify a rewrite, but when you answer “yes” to all of them, it should be an easy task to justify the costs associated with a rewrite.

The Rewrite

Once you’ve successfully argued your case and gotten the funding to move forward, this is when the fear sets in. Looking at the existing application at a high level, you have a good idea of what you want to build, but how do you ensure you get the detailed requirements right? How are you going to be sure that this time you get it right? You will want to make sure you choose the right technology and that you don’t build an application that is too brittle and inflexible for future enhancements? What will be different this time that makes this implementation more maintainable?

These are all good questions, but relax; you have a very good chance of being successful. Since most applications being rewritten were initially designed a decade or more ago, you need to be reminded that a lot has changed in that time. Even though we thought we had all the answers back then, we’ve come a long way and learned a lot in that time. All areas of technology have improved. Databases can handle many more transactions; storage is cheaper; there are multi-tenant implementations and don’t forget the cloud. I prefer to write applications using Java, and a dozen years ago it was in its infancy where frameworks like Spring were non-existent.

Processes and methodologies have come a long way also. Waterfall process has been used to successfully implement many important applications, but a quicker, more agile way of developing applications is vital to success in today’s world. Iterative development took a large step in the right direction, but now the Agile Development Methodology has made teams more productive and projects more likely to succeed (or fail) fast. While object-oriented development has been around for decades, the promises for reuse and maintainability are currently being proven every day.

So, once you conquer your fears and are ready to jump in, here are my top ten tips for things to remember as you consider rewriting your applications:

1. Design for Reusability / Be Object-Oriented

Hopefully by now all software development organizations know how to write good object-oriented code. For your application to be object-oriented means that you write classes of code that model your real world business domain. Your design leads must have a talent for recognizing where responsibilities lie and what one place in your system they should be coded. Avoid having multiple copies of the same code in multiple places as this becomes one of the huge maintenance pot-holes of the future.

2. Use a Layered Architecture

Which User Interface framework are you using? Which Persistence framework are you using? While these decisions are important, don’t tie yourself down. Layer your application so that you isolate the business domain, data persistence, services/business rules, and user interface. This layering will allow you to more easily change out a layer if necessary, while also enabling reuse and integration by other applications.

3. Choose your technology wisely

For some organizations, this is an easy step because technology choices are made by overarching organizations. For others, however, this becomes one of the more likely areas to stall. You can easily spend months reading about, evaluating, and hopefully prototyping different frameworks and tools. And just when you are about to commit, someone tells you a horror story about the one you’ve chosen. My advice is not to choose the latest and greatest of everything. Go with proven technologies that are still growing and evolving and especially look at what skills developers are investing their time in. Not all teams can ramp up quickly enough to implement a new set of frameworks on their own. If you have to hire or contract for additional skills, make sure the technology is one that allows your team to grow into it.

4. Find a leader that has done this before

Existing teams often have strong technical leaders that have been entrenched in the existing implementation and technology and who hold the keys to that embedded knowledge about the application. These leaders will be very important for the rewrite, but you also need someone who knows how to lead a rewrite effort. Too many times the existing resources are convinced that it will be too hard to rewrite the application and you will need someone with a fresh perspective who knows how to take your 4-ton legacy application and turn it into a svelte 500 pound dynamo.

5. Be Agile / Keep teams small

I am a huge fan of the Agile Development Methodology, not because it is the process of the day, but because it lets everyone on the team, including managers, developers, testers and technical writers focus on what gets the job done right.

One term you will hear associated with Agile Development is “fail fast.” This doesn’t mean you have less chance for success with Agile, it means that if you have made a choice that is not going to work for you, you will find this out sooner rather than later. Also, Agile is scalable to your team needs. If this rewrite will take 50 people to achieve your goals, organize into multiple smaller teams that can stay focused and spend less time trying to keep one large team on the same page.

6. Get Started Early

This tip does not mean jump in without in planning, but it does mean don’t wait until you have every single one of the answers before making progress. Many organizations want to know how long it will take to complete the rewrite that, by the way, is going to use brand new technology with a team that has never worked together before to implement requirements that aren’t well documented. Yes, these types of estimates are needed for getting funding and for acquiring resources, but you won’t really be able to validate that these estimates are close until you get started.

Early in the process, even before you know exactly which technologies you will be using or what design approach to take, form teams and start developing prototypes. Sometimes the word “prototype” implies throw away. In my experience, more times than not, the prototype becomes the base for the rewrite. Some of the code developed during this time is thrown away but that is a good thing. It is better to find out something was a bad idea while early in the cycle with a small team than later on – when it’s really hard to steer in a new direction.

7. Embrace Refactoring

Hopefully, you’re not still measuring productivity based on lines of code. There have been many occasions where the most productive days were spent eliminating lines of code. I have found that it is much more productive to write code early, before all issues have been flushed out, and then refactor once new information arrives. This is especially true when defining an inheritance hierarchy. If you have only one subclass, but know that others are coming, don’t subclass yet. Wait until the other subclasses surface and then refactor. One of the worst pitfalls for rewrites is the fear of refactoring. No one can get everything right on the first pass and trying to do so will be more expensive than doing it the best way you can now and refactoring later.

8. Automate Testing

Actually, you cannot embrace refactoring without automating testing. The first time you code a part of the system, you should not call it done until your automated tests are also complete. If you are using 2-week sprints for your development, and 7 sprints in you decide to refactor functionality that was completed in sprint 3, you need some way to make sure all the previously working functionality still works. Automated tests provide you the confidence that your code is not fragile. If a later piece of functionality changes something that was already working, your test should show it.

Beware, however, that the automated tests are code too. These must also be maintained. Choosing the right set of tests is important. My advice is that all code at all levels needs non-trivial unit and integration tests, and that automated test scripts for testing the user interface should be minimized. UI tests are the most expensive to develop and maintain and if your unit tests below the UI are done correctly, your UI tests are mostly testing navigation and interaction. The bottom line is that automated tests to take time and effort but this cost will return some of the value on your project.

9. Focus on Maintainability

This is probably the topic that got you here. Your new system must be maintainable, extensible and not fragile. All of the tips above have a maintainability aspect to them so I won’t repeat them here. The one additional point I will make is that developers should rarely, if ever, be clever. While there are many very smart developers who will take pride in writing code in a way that saves a 1000 lines of code or 15 classes, this code is rarely ever understood by those who have to maintain it. Encourage your developers to follow established patterns, reuse code and frameworks, and to always write clear, understandable code.

10. Be Practical / Don’t plan too much for the future

My last tip is the one that I rely on the most. Be practical. Too many times, in an effort to avoid future enhancement problems, designers of the new system try to plan for everything. Even though you might need a someday support mobile devices or live in the cloud, if you have no current requirements, don’t introduce complexity into your application for it now. Good architects and designers can provide guidance on what to avoid that will make implementation of these technologies in the future, but don’t write code for anything you don’t already have requirements for. If you use a layered design, write really good object-oriented classes, incorporate automated testing, and embrace refactoring, you will be able to incorporate future requirements without a major overhaul.

Final Notes

Hopefully, for many of you, these tips seem like common sense and are behaviors that you’ve been employing for years. For those who have been locked away in your legacy towers for years and are afraid of coming down to the current world of technology; never fear. Application rewrites can be a huge success and can make moving forward into the future a pleasure rather than a burden.

— Keith Shakib,

  • Share:

One Response to “Don’t Fear The Rewrite”

  1. Lou Mauget says:

    Right on, Keith. You’ve described my intermittent world of migrating outdated technologies, tools, no doc, with nobody living that understands the code. Kick it and see what happens. I’m thinking of Cobol written before even structured programming was in vogue — literally from the previous century and millennium.

    Not so sure that pure object-oriented will always be the only choice for reusability or maintainability. We’re getting into multi-core exploitation at the same time we’re seeing mega-huge scaling requirements. Speed per core is flattening (perhaps until new paradigms like quantum computers). The functional programming of the academics and Lispers is in our faces now. There are discussions about nouns vs. verbs, mutability vs immutability, lazy vs eager, shared state vs. private state, software transactional memory, hot-deployment, and more. This could be painful for us “procedural” folks. :-)

    This is in no way a negative comment on your excellent blog post. Item one just dislodged an opinion about a possibly interesting future in Geek-World. I was born too soon.

    -Lou Mauget

Leave a Reply

Things Twitter is Talking About
  • Pssst... Our free monthly newsletter comes out tomorrow with dev tips/articles via email. Not on the list? Sign up:
    October 22, 2014 at 1:46 PM
  • How do we harness the power of callbacks without the confusing mess of nested functions in #JavaScript? Promises -
    October 21, 2014 at 2:18 PM
  • Pssst... Our free monthly newsletter comes out tomorrow with dev tips/articles via email. Not on the list? Sign up:
    October 21, 2014 at 12:05 PM
  • Did you know today is Clean Your Virtual Desktop Day? It really is: Celebrate by organizing your desktop files.
    October 20, 2014 at 4:50 PM
  • Don't miss the newest post from @bricemciver: Make Me a Promise - #JavaScript
    October 20, 2014 at 10:43 AM
  • RT @DZone: #Docker 1.3 Releases with Security, Signed Images, and Process Injection by @bendzone #devops
    October 17, 2014 at 10:04 AM
  • If you have 15+ years #Java exp, you don't expect to be puzzled debugging a null pointer exception. See an exception:
    October 17, 2014 at 9:51 AM
  • Many on our team attended the #Royals victory last night & @cdesalvo even got a selfie with the Gov. Go #KansasCity!
    October 16, 2014 at 3:39 PM
  • Interesting ExplainLikeI'm5 talk: Why do companies develop iOS first when Android holds 70% of the 'Smart' Market?
    October 16, 2014 at 12:26 PM
  • We're looking for a top-notch #Java developer to join our team. Learn more about our company culture & the role -
    October 16, 2014 at 9:08 AM
  • Want to learn to create custom #Java annotations & process them using the Reflection API? @jhackett01's tutorials -
    October 15, 2014 at 11:43 AM
  • Happy Ada Lovelace Day! It's a celebration of the achievements of women in STEM - if there's a woman in tech that you admire, tell her today
    October 15, 2014 at 9:13 AM
  • .@fpmoles We absolutely agree - thanks for reading!
    October 15, 2014 at 8:13 AM
  • With 15 yrs exp, @bmongar didn't expect surprise when debugging a null pointer exception. Why it puzzled him - #Java
    October 14, 2014 at 11:20 AM
  • #Royals fans with tickets to tonight's canceled game, here's what you need to know -
    October 13, 2014 at 4:23 PM
  • RT @UzilitySoftware: Watch as Wayne explains to the boss, Marvin, what an agile board is about. #scrumalliance #scrum…
    October 13, 2014 at 12:01 PM
  • Getting started with #MongoDB? (Flexible #NoSQL for Humongous Data) Here's a free cheat sheet from the folks @Dzone -
    October 13, 2014 at 11:10 AM
  • Brad Mongar's newest post is live on the Keyhole blog - #Java and the Sweet Science
    October 13, 2014 at 8:59 AM
  • RT @housecor: If users have share links to your web app like this: "Go to here. Then click here. Then here." You're doing it wrong. #de
    October 10, 2014 at 2:18 PM
  • CSS is 20 years old today! Happy birthday, #CSS - web design would not be the same without you.
    October 10, 2014 at 9:55 AM
Keyhole Software
8900 State Line Road, Suite 455
Leawood, KS 66206
ph: 877-521-7769
© 2014 Keyhole Software, LLC. All rights reserved.