We tend to steer our clients away from rewriting existing systems where possible, because it’s often a far more difficult task than it might look. However, there are valid reasons for opting for a more large-scale rewrite – for example:
- major systemic problems are holding back performance, blocking the possibility of enhancements etc.
- there are so many significant individual bugs that trying to find and fix each one would be a greater task
- the projected lifetime the code needs to continue operating over is very long
- to remove ‘blackspots’ – if the volume of legacy code is small compared to more substantial modern processes
In general a rewrite is desirable if the projected revenue benefits beat the costs to rewrite. This may seem an obvious statement, but our experience is businesses rarely perform this calculation, and seldom choose a rewrite for this reason. Be warned: if your in-house programmers have suggested a rewrite because ‘no one is using this language/software/technique any more’, they are thinking of their own convenience, and not about your business.
We can help you gauge whether a rewrite really is the best way forward for you – so that you don’t waste valuable time, money and resources chasing a solution that you almost had already.
If we do determine that a rewrite is best for you, then we will work to deliver it as promptly and painlessly as possible. Our expertise in legacy systems will enable us to get to grips with what you have already, so we can code it up quickly using a fresh, modern, object-oriented and modular design.
Approach
The most obvious way to replace any system is to start from scratch and put all the components in place until the original system is emulated. The main advantage with this approach is the high level of freedom it allows with design choices. In theory you can address all the complaints you had with the earlier design, and you are free to change things like the user interface to a completely new style. For this reason it is tempting to think a ground-up rewrite of a legacy system is the best way forward – and sometimes this is the case – but more often it can turn out to be far more complicated than originally anticipated.
Ground up Rewrite
The main problem with a ground-up rewrite is the length of time it’s going to take to get your new code up and running. Along the way you are going to find yourself rediscovering the same problems already met and solved in your original codebase; you’re going to think you can improve A by doing it using technique X, only to later discover this was tried previously – and that this is precisely the reason technique Y was ultimately used in the original. Battle-tested code often has a great many fixes and bolt-ons which may look mysterious, and may stick out sorely as ugly code – but may in fact have a very good reason for being there. It may be a mistake to simply assume the previous coders simply did not know what they were doing.
Indeed it is a good idea to verify you really do need to rewrite your system in the first place. If you conclude it is, then you should definitely question whether the ground-up approach is the best route forward – or whether a more iterative solution would serve you better.
Strangler Rewrite*
A “strangler rewrite” is the iterative solution we are best placed to help you implement. This method involves peeling away individual features from the original system and rewriting these in turn, until the entire original codebase is replaced. The advantage of this is that enhancements can be put into place during the rewrite, so that users see continuous improvements as they would with a system simply being enhanced. With sufficient attention to ensuring smooth integration, there should be no need for downtime, or for the user to be aware that at a given time some features have been written in a different format.
Inline Rewrite*
An “inline rewrite” is the main alternative iterative method. This involves the gradual rewrite of the codebase from the inside out – ie the steady replacement of individual functions and subroutines until the complete system is rendered much more tidy and manageable. Again this process can be combined with enhancements so progress is both in terms of maintenance as well as improving features. In fact the desire to upgrade a certain feature can be used to determine which area to work on next. An inline rewrite is inherently smooth, but is slightly more restrictive in what can be achieved. Generally this technique is more suitable if
- the original language is preferred
- the original system does not have major problems with overall architecture
- the rewrite does not need to happen urgently – since this option is usually slower and more gradual
- the existing system is tightly integrated and can not easily be broken into individual components
For more information about iterative methods of system replacement, and to get a specific evaluation of your particular situation, then please get in touch.
* We have aimed to use the terms “Inline Rewrite” and “Strangler Rewrite” in the same way as coined by Ben Sandofsky in his excellent talk at the Swift Summit San Francisco, 2016.
Case Study: Rewrite of a flight cost comparator application
Developer Evaluation
[This application] gathers flight pricing information from [various online sources] and provides instant cost comparison and flight route information… The original system was written using PHP and functions well within its original design scope. However the information delivery tends to be discontinuous – ie a static flight information page is returned to the browser, and so a further update can only be obtained by repeating the original search. A commonly encountered problem is drilling down on a listed flight to be taken to a page displaying the flight as no longer available… [The client] would like the system to be more fluid so that the flight page is updated in real time and more processing is dealt with on the client side… After comparing various options [the client] has expressed a desire to move over to a solution based on node.js – which in turn should be better suited for future adaption to a mobile application. The original has modular elements since it uses a Symfony 2 framework but there appears to be some duplication of functions and the logic is confusing in places… It is suggested that a section by section rewrite may be the best approach…
Steps taken & Time Breakdown
- ▬ Cloned app and set up dev environment
- ▬ Rewrote specific API and data gathering controllers
- ▬ Created and ran tests, pushed changes
- ▬ Rewrote general API controller
- ▬ Created and ran tests, pushed changes
- ▬ Rewrote page generation code
- ▬ Created and ran tests, pushed changes
- ▬ Wrote Documentation
Statistics
Result
Successful Fix