One of the most unavoidable things in software development is software aging. Technology, standards, patterns, and hardware are getting older and changing fast. One of the developer’s tasks is to maintain and keep the software up to date in order to make software age as slow as possible. Unfortunately, it’s easier said than done. New features and lack of resources leads to neglect of the software and makes it a so-called legacy system. Do you know how to save your system from becoming a legacy? Are you aware of the effects of having a legacy system? In this article, I answer these and some more questions.
There are a lot of definitions of legacy systems you can find on the Internet. Probably it’s hard to come across the fittest one. Wikipedia says:
In computing, a legacy system is an old method, technology, computer system, or application program, “of, relating to, or being a previous or outdated computer system,” yet still in use. Often referencing a system as “legacy” means that it paved the way for the standards that would follow it. This can also imply that the system is out of date or in need of replacement.
I fully agree with this definition and I think that it embraces the main aspect of the legacy system. I’ve heard once that the legacy system is the one that is not covered or is poorly covered by tests. I can’t agree with this definition because tests are not implying if the system is a legacy. You can write modern software without any tests but probably it’ll be harder to maintain which in turn can, of course, lead to legacy systems.
The legacy system term refers to:
- an old method, technology, computer system or application program
- a system which consists of outdated parts (patterns, standards, libraries, etc.)
We cannot consider the legacy system as:
- a system which is not covered or is poorly covered by tests
As it is described in the Wikipedia definition a legacy system is an old method, technology, computer system or application. The legacy system will be used in the rest of the article as a representative of all the above.
Why the legacy is so problematic?
A legacy system is hard to maintain and can engage too many resources, which leads to higher costs. Difficulties in maintaining software can make it takes longer to deliver new features to a customer and increase the chance of introducing bugs. Of course, this subject can affect different departments in your organization. From the business perspective higher costs of developing the system result in lower revenues. From the human resources perspective, the legacy system can make it harder to hire new employees (Who wants to maintain the legacy system?). And finally, programmers want to develop themselves and gain experience every day. They don’t want to maintain a big legacy system until they retire so there is a huge risk that some of them will give their notice. For programmers, work on the legacy system can cause less confidence in developing and deploying it to production.
I think that the aspects I’ve described above are good encouragement to think about protecting your system from aging fast. Continuous refactoring can be a good way to do this.
What if I already have a legacy system?
If you already have a legacy system and you don’t want to turn it off, you should think about refactoring or even rewriting a whole system. But wait… rewriting a whole system to the new one? Yes, I know that you don’t have enough resources to write a new system and continuously maintain the legacy one. I also know that you have a lot of fancy ideas about new features which should be released as soon as possible. But I also know that if you don’t rewrite/refactor your system you’ll get in trouble in the future.
All the things I’ve mentioned above sound horrible but don’t panic and relax, please. There is a way to rewrite your system slightly and safely without using too many resources and, what is very important with the possibility to continue maintaining the legacy system. The way I have in mind is called “Strangler Pattern” (Strangler Application Pattern or even Strangler Fig Application). This metaphor was firstly defined by Martin Fowler in his article “Strangler Application” which was then renamed to “Strangler Fig Application” because of its close relation with Strangler Figs which is described in Fowler’s article.
What is Strangler Pattern and what it is about?
Strangler Pattern is a way of gradually rewriting the legacy applications to keep them up to date and make them easier to maintain. As Martin Fowler describes, the goal is to create a new system around the edges of the old one in order to “strangle” this old system. This is an iterative method and can take several years until the old system is gone but thanks to this you can safely migrate your old system to the modern one.
Considering that systems are continuously becoming legacy, we can say that the process shown above is repetitive. It means that we are rewriting legacy system to the modern one which will be legacy in the future. Martin Fowler wrote “Let’s face it, all we are doing is writing tomorrow’s legacy software today.” which is an essence in nowadays software development and everyone who is responsible for any system should be aware of that.
How can I start?
Strangler Pattern in theory only describes how it works and what benefits you can get from using it. In practice, there are a couple of different strategies and approaches related to the specific programming language you can use to rewrite your legacy system to the modern one.
Choose the migration strategy
There are two main strategies listed by Martin Fowler in his article:
Event Interception – a strategy based on the stream of events. If you have an event-driven system that sends important events to the outside world, this strategy is probably the best choice for you. For more information please read Martin’s article.
Asset Capture – the strategy which is based on identifying key functional parts of your system and gradually rewriting/refactoring them in a modern way in the new system. This strategy can be running along with Event Interception. For more information please read Martin’s article.
Find an approach which meets your requirements
There are also several approaches to how you can start migration between legacy and modern system for web-apps. Below are some of them:
Load Balancing – load balancing is an approach usually used on the Web Server side. The Web Server decides to what destination a request is redirected. There is an interesting article with some use cases called legacy application strangulation case studies.
Front Controller with Legacy Bridge – it consists of running a proper script for specified requests in the front controller of the application. The Front Controller checks which script can handle specified requests and runs this script waiting for a response.
Legacy Route Loader – it consists of preparing an application routing in order to run a relevant controller for specified requests. The main difference between this and the previous approach is that in the previous approach both applications are fully independent and some of the common parts are duplicated (e.g. routing). In this approach, a legacy system is run inside of the modern one which can also interact with some parts of this legacy system.
Note: If you know more approaches to migrate legacy systems using Strangler Pattern, please share it with others on comments.
This article was meant to show you that the software aging is a common and repetitive problem. You should understand that protecting your system from aging fast is important for you and your company. It also introduced the Strangler Pattern as a tool that can help you to deal with the legacy system. Software development is a continuous process and regular care extends its vitality.
In the next article, I’ll show you a use case of Strangler Pattern for migrating the old Symfony 1.4 application to the modern Symfony 4.4.