Ground-Up Rewrite = Flush Your Company


Software engineers love rewriting old code.  I’m a software engineer, and whenever I look at my own older code (as in more than  a month or so) I get an instant itch to rewrite it.  I’m a bit embarrassed by it, and I think that for various reasons, I can do it better now.  It happens even more when I look at somebody else’s code, because I also assume they must not be nearly as clever as I.  When something’s WORKING we still want to rewrite it, so when a product or component is causing maintenance or performance issues, there is usually a very strong case being made that it needs a ground-up rewrite.  We say things like “we won’t be able to improve the graphic performance unless we completely rework it with a different set of libraries” or “this should have never been developed in Perl, we can’t scale unless it gets redone in C++” (direct quote, by me several years ago).  Or just “this program/class is an incoherent mess, I’m writing a replacement”

Don’t do it.  This will probably kill your company.

Even if it has issues, your production code is the result of say two years of development, of which something like 20% was the fun part of writing shiny new code to solve a problem, and the other 80% was a long slog of tweaks and bug fixes.  Guess what, when you replace that ugly code with your new shiny code you just gave up hundreds if not thousands of man-hours spent improving things.  You re-introduced old bugs and, worse, added new ones that you don’t know about yet.

And the more strategically horrible part of this, is say you spend 2 months writing the new version.  Don’t forget, it will take you twice as long as you think.  During those two months you continue running the old code, but you stop maintaining it because it’s going to be replaced by something amazing “any day now”.  In my experience, you end up with a legacy system that has fallen way behind where it should be, thanks to lack of attention, and a new system that can’t be successfully rolled out because in a production environment it’s not performing as expected.  You now need to invest another significant chunk of time finding and fixing the bugs in it, which you had already done on the old version.

Now you just wasted huge amounts of your most precious resources – time and momentum.  Your customers have wandered off and your competitors just ate your lunch.

The other trigger for this, where there is a legitimate need to do a rewrite, is usually for performance issues.  Such as replacing the Perl code with C++ (bad Jeff).

What should be done instead?  Both situations will arise…


When you have legacy classes/components/scripts that are so full of special cases that they can’t be maintained without causing stability problems you DO NOT REWRITE THEM, you pull out functional parts bit by bit, and you name variables and functions bit by bit until it’s clear and well-organized.  And at no point did you add or remove a single line of code that was not there previously.  The code is unchanged, it’s just laid out much better and you can now work in it with confidence.  All of the little fixes and special cases are still there and, perhaps most importantly, there was NO point in time when the code being edited could not be used in production.

Similarly, when you have to replace a program or component in its entirety, you approach it with a refactoring mindset but it’s a bit more complex and has a bit more risk.  In this case, sooner or later you’re going to replace the component with a new one, and it might be in a completely different language, so you can’t use the classic code refactoring techniques.  Instead, you get as close to that as you can.  First, you work to lock down the real functionality of the legacy code with an exhaustive test suite.  This will likely take you longer to do than actually writing the new one, but it’s the only way you can ensure you stay true to the current behavior.  Look at the code as you set up the tests, ensuring that all the funny special cases and outliers are tested.  Generate tests from three months of live usage, ensuring that you handle everything that users/environments actually try.  Next, keep in the refactoring mindset by making the minimal changes possible.  For example, if I were moving a program from Perl to C++ I would actually have the legacy Perl program call a new C++ program and use its output.  This way I can refactor my code from Perl to C++ line by line and function by function, until eventually I still have a Perl program that actually calls a C++ program to perform ALL of its functionality.  All the Perl program does is invoke the new version and return its output.  Now you can take the final step of replacing the tiny Perl with the new C++ and everything should continue as before.

This process allows you to accomplish BIG architectural changes without ever having code that could not be in live use.  If something unrelated breaks, you can fix it on the latest version and push it out, and you’re not maintaining “production” and “future” versions separately.

If I were undertaking this right now, I would also like to pair it with continuous deployment, so that as I made each tiny, safe, change it went live and any errors would be detected immediately.  Also, as mentioned, refactoring is best done with the safety net of a great unit and integration testing framework.

If you want to learn more about refactoring, most learn from The Bible: “Refactoring: Improving the Design of Existing Code” by Fowler, Beck, and (apparently) a dozen others.  I’ve also learned some great techniques on using this practice to improve architecture from “Refactoring to Patterns” by Josh Kerievsky.  Also, Martin Fowler has a website about refactoring at that appears to have some good resources.  Let me know of any other favorite resources in the comments.  I follow Kent Beck at @kentbeck.

Joel Spolsky (@spolsky) wrote a fantastic article on these problems TEN YEARS AGO and I still see this happening.  I think people need reminded of it regularly.

Joel On Software: Things You Should Never Do, Part I

If you write software or manage people who do, you need to go read his old posts now.  It’ll make you look smart 🙂

The Startup Library


I love books.  I’ve done almost all of my learning from books and web pages.  So following up on a post by Boris about finding startup books in Vancouver, I wondered what would be the required reading list for a startup (or a Bootup cohort company).

Here’s my tentative list, from personal experience.  What else needs included?  Is there a great Drupal book?


  • Four Steps to the Epiphany – Steve Blank – on my TO READ list, the bible of customer development.
  • Startup Lessons Learned – 2008-2009 – Eric Ries – I’m not listing blogs on this post, because there’s plenty of resources for that.  But I get to cheat and include this book form compendium of Eric’s posts.  This material is invaluable, for the detailed discussion of continuous deployment practices and the lean startup business model.


  • Test Driven Development by Example – Kent Beck: the how-to book for applying test-driven development (a great Extreme Programming technique for rapid reliable code, and very applicable to continuous deployment) and unit tests.
  • Refactoring to Patterns – Joshua Kerievsky: if you’re writing a lot of code hopefully you’ve read both Refactoring and Design Patterns, but this book puts the two together and gives you strategies for migrating spaghetti legacy code to nice patterned code.
  • Facebook Cookbook – Jay Goldman: this is a great book that covers all aspects of Facebook platform and Connect programming, from ideation and planning to viral marketing and API code samples.  The only downside is that the API is constantly changing and portions of this were already out of date when I bought the book last year.


  • Getting Things Done – David Allen: on my TO READ list – sounds like the least gimmicky, most lean and effective way to stay focused on what’s important and cut out your wasted cycles.
  • Getting To Yes – Fisher,Ury: how to negotiate effectively in all areas of your life (with employers, investors, spouses, fishmongers) by avoiding positions and addressing underlying interests.
  • The Seven Principles for Making a Marriage Work – John Gottman: <preach>Some things are more important than your next round or release.  Without strong support at home you can’t succeed, and whether your startup succeeds wildly or flames out, you will have failed if you lose what’s important to you.</preach>

Please, let’s fill this in with more.  And then get Chapters or Amazon to sponsor a set for new cohort companies 🙂

Motivate with PROGRESS


In a recent HBR article (What Really Motivates Workers) it was revealed that workers are motivated less by the usual suspects (incentives, recognition, …) than we thought and that in fact progress in their work is the key driver of daily satisfaction.  How can we take advantage of this in software development to crank up real and perceived progress, and keep workers happier on a daily basis?

First, it seems we’re an industry uniquely situated to take advantage of creating perceived progress.  I don’t mean false progress, but with the real time metrics available such as compile errors, bug databases, unit tests passed or test runtime, we have the tools to demonstrate progress in several ways depending on the project.  The trick may be to identify the ones that are most valuable to your product, and to keep some perspective on how much you emphasize them.  If you keep cheering up your team by pointing to the diminishing bug list, you’ll have a hard time rallying them when a large dump of bugs comes in from new testing.  Keep it focused on customer satisfaction and percent of code under testing.

Second, there are methodologies and tools for software engineering that support constant progress and prevent the kind of backslide that kills morale and motivation.  Specifically, I’m thinking of agile methods that cut out time spent on exhaustive planning and requirement specifications that doesn’t feel like progress to the person writing it, and creates the opportunity for big negative progress when it turns out they’re misguided.  Then tack on test driven development to allow constant, incremental additions while locking out the possibility of backsliding again, and continuous integration and deployment to keep your work rolling forward instead of halting and going back.

These are very pragmatic, and well tested methods that, used together, will hugely increase the number of days your team can go without a big backslide, adding incremental improvement or capability day in and day out.  And, according to the article, this is a key driver of motivation.  So in addition to the benefits we already knew about (faster results, less wasted time, better tested code, no ‘ocean boiling’ integration and release cycle) we can now say that agile methods keep your team happy and motivated.

What other techniques support constant progress?