Having helped many clients on their journey to next generation technology, we often tackle the issue of modernization strategies for legacy code and platforms. From our experience, we typically see three options under evaluation: a complete code-re-write; doing nothing; or gradually refactoring/replacing code.
In this post, we provide our view on each option.
Option #1: Complete Code Re-Write
Ideally, building a platform using modern design and languages, using the best patterns and practices your organization has made routine is by far the best strategy. Realistically, however, completely re-writing legacy code rarely happens, and when it does, it’s rarely successful.
Your business and customers cannot pause for months (or years) while you re-write code. You have to remain operationally competitive and service your customers. Even companies that have experienced plenty of functional issues over the years continue to perform bug fixes, add incremental features, and evolve their platforms. They simply cannot afford to risk a major one-time overhaul.
Another consideration here is the scale of a company’s code. We have seen companies grow through acquisition and have as many as 40 different products in their portfolio. Most often, the decision to rewrite or not is made on a product-by-product basis, with strategy teams figuring out how they can best combine code bases, platforms, etc. Other companies have just one major product, but even they likely have it as an integrated suite of sub-products that connect via services. In some cases, individual services require a complete re-write, but rarely does it become a complete code re-write. Business simply cannot stop while a re-write occurs.
For most companies, a major overhaul of legacy code could be disastrous. It would not be economically feasible to hire an entire coding team and build something new in parallel to ongoing operations. When finished, the ‘big bang’ release risks being either underwhelming to users or so new in appearance that users feel intimidated and do not adopt as planned. Of course, the longer a rewrite takes, the higher the risk… and after all, isn’t that one of the biggest weaknesses of the waterfall method? “Everyone hold on for two years before we know whether this new architecture really works or not. In the meantime, we will spend most of the company’s available budget on this behemoth.” Not so much.
In the end, complete code re-writes are simply not practical, and fraught with risk. Exceptions to this are independently deployable services, interacting with the rest of the ecosystem via API, with a well-established test suite.
Option #2: Do Nothing
OK, doing nothing is never an option. At the very least, even a product in maintenance mode will have mission critical bugs to fix. But beyond that, there are degrees of investment that reflect the company’s strategy with the product. We typically see products as either maintained (mentioned earlier), or sustained (minimal new functionality added to keep the customer base). However, in each of these cases, continued work on the existing code base is costlier and riskier as the language and/or underlying architecture continues to get older and less efficient.
While companies with 30 or 40 products may choose to maintain certain products, companies with 1-5 products will always need to do something with their legacy code to stay competitive, relevant, and viable.
Option #3: Gradual Refactoring or Replacement
As we have seen with our many client engagements, this option is the preferred of the modernization strategies for legacy code. There’s usually budget already allocated, as companies tend to track 12-15% of revenue for product R&D investment. If you are investing in a product, that means you are refining it, adding new features, fixing bugs, etc.
It would be good to address nomenclature at this point. “Modernization” refers to evolving an architecture using a modern, service-based approach. “Re-platforming” refers to moving an ecosystem off of bare iron into a set of virtual machines (e.g. VMWare) or containers (e.g. Docker), leveraging a Platform-As-A-Service (PaaS) solution (e.g. Pivotal Cloud Foundry).
Companies that are dealing with old software running on a rack in a data center (which no one wants to touch for obvious reasons) will look at re-platforming as a stepping stone to a modernization effort. Re-platforming can help them de-risk their infrastructure and solidify their Disaster Recovery plans and capabilities.
The decision ultimately comes down to refactoring or replacing components. You are taking an incremental approach, identifying modules that can be carved out and turned into services, and, over time, modernizing your platform.
That assessment basically arrives at a decision by answering a wide range of questions, such as:
• Which components are my company’s primary focus?
• Think about Core Domain; Intellectual Property; main market differentiators.
• Am I just refactoring or replacing them?
• Is the language and platform dated; does it hinder my ability to recruit?
• Are there open source alternatives or 3rd party services that I can use?
• Do we want to renovate the UI? If so, when do we want to push people to a new user experience?
• Think about continuous user acceptance testing
• Be aware of the requirement to run the old UI on the new platform (for slow adopters)
• Are there major bugs, which if fixed, resolve most (if not all) priority issues?
• Which customers do we risk losing without an upgrade? How large is that market segment and how important is that segment?
As you can see, you are not just answering technology questions when you make decisions surrounding refactoring and replacing legacy code. You start with strategic business drivers, then flow down to the supporting code found in architectural components and products.
Give these discussions the space and attention they deserve; they could reveal some misalignments that will help clarify future direction and next steps.
This post is part 1 in the series of modernizing your legacy code. Stay tuned as we next discuss the approach you should take to make your architectural decisions.