Getty Images

Tip

What is the strangler fig pattern, and how does it work?

Imagine owning a motorcycle that needs fixing up. Instead of disassembling it and spending months rebuilding, what-if you replaced one part at a time so you could keep using it?

Migration from a legacy application system often requires heavy code rewrites.

However, it's possible to implement a pattern that slowly deprecates a legacy system over time while incrementally adding new functionality. This approach, coined by Martin Fowler as the strangler fig pattern, gradually updates legacy application systems -- colloquially known as the "big ball of mud" -- while keeping them running in production.

Before launching a complete system overhaul, consider the strangler fig pattern, its benefits and challenges, and review step-by-step instructions for its implementation, along with example use cases.

What is the strangler fig pattern?

Picture a motorcycle that could use extensive overhauls to improve its performance. One option would be to disassemble the motorcycle and spend months rebuilding it. But will it run after you've replaced every part? And what-if you want to use the motorcycle but can't while it's in the garage?

The objective is to retire the legacy system by gradually refactoring individual features from the old paradigm into a new one.

Another strategy is to replace one part at a time, ensure it works as expected, and then move on to the next component. This has three significant benefits:

  1. The motorcycle will likely still run even as parts are incrementally replaced.
  2. If a fix or replacement doesn't work, it'll be much easier to identify the source of the problem.
  3. The result is an updated motorcycle that never stopped running.

The strangler fig pattern works similarly. Rather than dismantling an application system and rewriting its code, this pattern allows development teams to incrementally update sections of code and functionality without completely shutting down the system. The objective is to retire the legacy system by gradually refactoring individual features from the old paradigm into a new one.

This means the migration process can proceed iteratively rather than in a complex rip-and-replace scramble. Instead of implementing a second codebase, development teams can focus on refactoring one service or function at a time. This eliminates the need to create two separate development teams -- one that manages the old code and another that manages the new code.

When to use the strangler fig pattern

The strangler fig pattern provides a roadmap for migration, but not every project is an ideal candidate for the pattern. While it is typically associated with updating legacy applications and transitioning monoliths into microservices, here are some additional factors to consider when determining whether to implement it:

  • Unsustainable development. Continued development of a legacy system is no longer sustainable. A codebase can become so littered with technical debt that small changes become expensive. Or, concerns are not separated, and a slight change in one bit of code creates unexpected problems in a second area.
  • Unexpected growth. Some systems might meet functional requirements, but the architecture cannot handle the load. As demand increases, an organization might need to transition rapidly while still operating.
  • Demand for parallel development. Multiteam development is infeasible due to software systems lacking clean interfaces and separation.
  • Tech obsolescence. The organization might want to sunset a technology, but it could be core to the business, and waiting years for a rewrite is unrealistic.

Pros and cons of the strangler fig pattern

Evaluating the benefits and risks of the strangler fig pattern is a critical step in the migration process.

Advantages of the strangler fig pattern

  • Business continuity. The pattern helps ensure an organization's systems remain in continuous operation even as it transforms.
  • User experience. It mitigates disruption to service and facilitates standard interactions from a user perspective.
  • Risk management. If an issue arises, it's possible to revert changes relatively quickly.
  • Reduced upfront costs. A rewrite approach typically requires two changes for every feature -- one in the old system and one in the new. Using the strangler fig pattern can help eliminate dual entry maintenance and lower the regression test burden.
  • Control long-term costs. Without taking systems completely offline, organizations can determine their own migration priorities and pace in accordance with budget constraints or limitations.
  • Time to market. Development teams can launch new features almost immediately.

Drawbacks of the strangler fig pattern

  • Technical debt. Residual technical debt from the old system will likely transfer to the new one unless addressed during migration. Shortcuts made during migration can also add to the new system's overall technical debt.
  • Data consistency. Without careful management, synchronizing or converting data between systems could lead to duplication, inconsistencies or errors.
  • Complexity. The pattern adds a layer to the system, which could slow performance and complicate debugging efforts.
  • Legacy skills. An organization will need developers who understand the old technology or, at the very least, know how to extract and move it to the new system. Otherwise, translating and transferring the code could create a bottleneck constraining delivery speed.
  • Long transition period. Without a clear sunset strategy, the two systems might live side by side for years and increase costs in the long term.

How to implement the strangler fig pattern

The strangler fig pattern might seem complex on the surface. However, it's straightforward to implement if teams follow the correct procedure. The diagram below illustrates the steps involved in implementing a strangler fig pattern.

A diagram of the seven steps to implementing a strangler fig pattern migration.

One of the key elements of the strangler fig pattern is the facade interface, which serves as the main point of interaction between the legacy system and the external applications and systems that call it.

When code resides in a single module that tightly couples multiple services, external systems cannot identify which code blocks are associated with a particular function. This can slow response times and make performing accurate testing on individual services virtually impossible.

The facade interface will help external apps and systems identify the code associated with a particular function and obscure the underlying legacy system code. To deal with this, the strangler fig pattern involves creating a facade interface that helps developers expose those individual services and functions as they break them out from the monolith. Eventually, the code behind the facade will shrink as developers write, test and deploy new code.

The strangler fig pattern in practice

Example 1: Object-oriented programming

A class containing thousands or tens of thousands of lines of code is sometimes called a god class. Modifying this class is often one of the most painful parts of code update projects because it contains many unrelated methods. Any method can access and potentially modify variables it was never intended to, meaning a change in one place might have unintended consequences elsewhere.

To apply the strangler fig pattern to an object-oriented system, identify related variables within a large class and extract them into a smaller class. This new class will encapsulate these variables and safeguard them from changes, allowing modifications only through its defined interface. When modifying a chunk of code associated with a particular feature, move that code into a new class dedicated to the feature. As programmers make changes and develop new units of well-structured code, the god class will gradually deteriorate and can eventually be removed entirely.

Example 2: Database

Most enterprise-grade databases now work on trigger-based mechanisms that run code in response to events and automatically record the changes that occur. This makes it possible to maintain a second system that can also run and track those events. Whenever a change occurs in the legacy system, configure a new system to capture those changes and provide reporting. Over time, modify those events to route directly to the second system. Eventually, it will be possible to retire the old database completely.

Moving forward

Before committing to the strangler fig pattern, there are a handful of alternatives to consider and weigh the tradeoffs for, including the following:

  • A ground-up rewrite, which can be expensive and might limit, if not completely halt, an organization's ability to launch new features for some time.
  • Transition to a vendor's replacement system, which can have commercial costs, training requirements and vendor lock-in.
  • Continue to make maintenance patches on an older legacy system, which can strain resources and potentially add to technical debt.

If the strangler fig pattern is the right choice, identifying a starting point for implementation might be difficult. One simple strategy is to start with features already under active development.

The Boy Scout rule of software engineering advises programmers to leave the code a little better after every touch. The strangler fig approach embodies this sentiment, simultaneously allowing teams to improve the pace of development, reduce regression problems and continue to add new features.

Matt Heusser is managing director at Excelon Development, where he recruits, trains and conducts software testing and development.

Dig Deeper on Enterprise application integration