The Strangler Fig Pattern
Often in my career, I didn't just don't get to build from the ground up. Facing an existing legacy system bogged down by technical debt and active users dealing with bad UX, it is only sometimes feasible to rewrite everything in a vacuum and take a few quarters to deliver something tangible to the business. Risks are involved in assuming newer is better, budgets are tight, and sometimes localized issues demand immediate attention. As a polar opposite of a Big Bang rewrite, one particular approach stands out: The Strangler Fig pattern.
Much has been written about the Strangler Fig Pattern, from Martin Fowler's original 2004 post to AWS, Microsoft, Shopify, and many others. Read up if you need to familiarize yourself with the approach; I won't rehash all of that other than the metaphor of wrapping the old with the new and removing the former when ready, which is a tried and true approach. The concept is abstract and can take many shapes and forms in practice, depending on whether you're dealing with things like classes, services, or application layers.
The Monolith
One class of web applications I've faced in projects was the monolith. When approaching a strangle proposal, you want to look for natural fault lines in the codebase, typically where the separation of concerns plays out. Modules, view layers, and APIs are all great options and tend to delay the need to re-implement the entire business logic early on. Unfortunately, monoliths that make good candidates for rewrites are the ones that had those lines blurred over the years of development, and everything turned into an ungodly mess of spaghetti.
The good news is that typically, a database is involved, and it makes a natural starting point for planning out your strangle. In principle, you can build a model abstraction over the existing database entities and use it to drive your new front end. In a couple of particular examples where this played out well, the goal was to improve the end-user UX fast and ignore all the adjacent features tied to administrative work on the app. Implementing a middleware read-only REST API and a React frontend allowed us to address the business's immediate concern and approach the somewhat less crucial internal admin features when everybody already felt we were on the right track. The users got a spiffy new UI, and the internal teams had the time to work out their requirements, which were implemented in the new stack later.
Recommended by LinkedIn
Data Migration
Moving away from legacy systems usually involves a data migration step, carefully executed at launch time. With the strangle pattern, this concept is a little more fluid and can happen naturally over time as you replace the old code. One good example I can think of was a project where we introduced a new authentication layer on top of the old code, which created a copy of the user object in the new database as the user logged in. As users interacted with the new codebase, they were migrated over gradually. When the time came to cut the legacy cord, the decision was made to abandon the legacy system and the inactive users.
Performance
Someone could point out that adding wrappers like this might impact performance, and they would be right. In practice, however, this never turned out to be a problem; the performance impacts were small and irrelevant compared to the benefits of solving the actual issues. Ultimately, performance constantly improved as connections to the old system were cut.
The Strangler Fig Pattern is a versatile way of outgrowing legacy code bases and an alternative to a precarious and expensive "everything at once" rewrite scenario. I often like to use another metaphor: rebuilding a car in motion. Amazingly, in the world of software engineering, this is a far less scary notion to consider and often better than the alternatives.