Re-engineer v/s Rewrite
We are engineers (can be safely generalised to humans), who at heart enjoy building not extending/enhancing/improving
Disclaimer: doesn't mean we don't enjoy extending/enhancing. I strongly believe in the philosophy of -- You touch it, you improve it!
"This is driven by the fact - programmers think old code is messy as Joel Spolsky writes -- It’s harder to read code than to write it"
Having said that, programmers use tonne of external libraries & modules to avoid re-inventing the wheel. And yet, if you ask them about the code he/she has inherited, the answer would be a mix of:
"oh this is legacy code, has code smells, long functions, too many branches, no documentation, less tests, cannot seem to understand why this design was chosen"
Alarmingly, when the same programmer sits to write code, he/she would avoid writing documents in the name of following an Agile process (no documentation - a mis-understood term).
In my experience, every product build/ project starts with being fully Agile but as complexity increases, Agility starts to suffer. This leads to the 2nd law of thermodynamics: Entropy. Refer Software Entropy - @pragdave & @PragmaticAndy. More on this in a separate post, lets get back to the problem and choices.
What are the choices
In my experience, re-engineer (or better refactor) v/s re-write is no different than Buy v/s Build decision. Each choice has supporting facts and one must choose based on circumstances. Like Neal Ford in the latest book -> Software Architecture: the Hard parts says:
every architectural decision involves trade-offs and our primary responsibility is making design decisions that consider those trade-offs.
In this case, typically you end-up picking one or a combination of:
The pragmatic approach is to choose option #3, however,
Irrespective, if the choice is to follow option #3 (which is always my default choice), make sure to involve trusted customers (for feedback loops and battle test new code), sprinkle new cool features (to keep excitement), celebrate the rewrite and avoid treating the team managing existing code as side job-keepers.
Our story/ What were we trying to do
We had an existing working system which was serving a few hundred thousand customers. It was a working application, however, team had constant complains about a few challenges:
All of these can be solved with #3 - being pragmatic. Hence, the option to re-write was not an option.
No surprisingly, the team wanted a full rewrite. Hence, we started with an answer "NO" - not to rewrite, but, then, we put all the trade-offs to justify rewrite and eventually we took an org-wide decision to rewrite the system.
Why did we choose to rewrite
It is important to understand the choice of rewrite even though everyone was somewhere in agreement to avoid a full rewrite. We took a deeper stock of the challenges team was facing - symptoms of the problem (not how they manifest itself).
Recommended by LinkedIn
Symptoms are deep-rooted which manifests itself in different ways.
We found that the design of offline batch file exchanges (no direct API integration) was conscious - due to the limitation of first set of customers. Additionally, since, this system was one of our first, it had nuggets of customer identity management, audit-ability, transaction management (which are clear boundaries for components) jumbled into one single module.
After detailing each trade-off and the associated challenges team faced, it was becoming convincing to start (still directionally) with option #3. One of the important design consideration here was Composability - assemble components from other parts of the organisation.
We set ourselves for rewriting (to prove the strong NO, I had initially), because we aligned it will help fix decisions from past, and it would let us move the product forward at the same time - for larger scale.
How did it go?
After the decision was done, we laid down a full scaled plan - time, blue-print of new architecture (although this evolved as we progressed, starting without a blue-print for such big activities always leads to disaster), features (including parity), capacity.
This might sound anti-Agile? (or does it?) but without this level of planning, it becomes fairly difficult to tap the progress and track the direction (moreover, if you were to deviate, without having a plan, deviating the direction becomes a difficult decision). Not surprisingly, with this level of detailed planning, it helped us become more convinced that the other two choices - refactor & strangle, would take more time (at least on-paper).
One of the first thing we did was, ring-fence the team and make them familiar with the design blue-print and product decisions. One of the important goal was to compose the components, reduce silos and build comfort in the engineers on the new system. We introduced cross-pollination among programmers to make sure everyone gets a flavour of all components - including exposing FE specialist with DB schema designs. Even though the team was new - they started to run at fast sustainable pace for months, building existing and new features. The decision to introduce a new set of features kept the team motivated.
Did we hit the timeline?
NO, we were delayed but with the decision to include feedback loops with one existing and and a new customer helped the team. It helped product to re-jig some of their priorities shaping the system as a new avatar of the old (not a remake of the old).
Summary & learnings
I have been part of 3 (the previous ones were massive) major rewrite and after each I conclude:
we should avoid full system re-write and yet been involved in 3 such journeys
Always and always start with a "NO" and challenge yourself/your team to justify a re-write, and do it only when all trade-offs have been considered/ visible. There are many things to keep in-mind for a major re-write, some important tidbits to be aware:
there are 3 variables - scope, time, cost
You would still run into issues, timeline won't be met - there will be challenging months that you’ll never get back but, hustle through the process, the rewards at the end are satisfying.
In all my 3 experiences, treating re-write as a religious org-wide event has a lot of benefits:
Will I choose to re-write again, the answer would be "it depends" or rather a "NO". But, if I choose again, I would always look for strategic benefits in a re-write - for the customers, for the organisation and for the team.