How to Refactor Legacy Code
Coding (Php 7.x)
The definitive guide about the Anti-Corruption layer
Who is this post for?
Here we talk about DDD, design patterns, and the Anti-Corruption Layer.
If you are not quite there yet you might start with:
As a kid, I used to love wandering around and exploring every old room when I was visiting my grandmother’s house.
It was not so rare to find, among those old boxes, letters, and yellowed newspapers, amazing discoveries.
Especially from the eyes of a 5-year-old kid.
I still remember quite vividly the one time I came across an odd-shaped brass joypad with numbers on its side and a date engraved on the bottom.
As you might have already understood, despite being made of metal its rest came to an end quite quickly, and in just a few minutes that thing was split apart into many pieces.
More often than not, many of these antiques are so delicate that it is smart to just leave them alone and limit me to watching them.
Today, things have changed and the situation is not quite the same, but, for certain aspects. I felt the same vibe.
In fact, I am currently refactoring a ~10 year old API into something more modern and I must say, the task does not lack challenges.
Like the ones of you that have worked on legacy code, The sensation of wander and astonishment hit me multiple times a day.
Usually, they are accompanied by vivid exclamations like:
- Who the heck wrote this?
- Why on earth there is this loop here?
- What am I doing with my life?
Luckily it is not 1925 anymore and people have developed many great strategies and patterns that help us not break down our code like an old brass phone.
As I learned at a young age, sometimes, It is smarter to leave stuff alone.
One of those brilliant people I was mentioning above is surely Eric Evans.
He is an author and came up with the DDD idea.
What is DDD?
Imagine a phone.
A phone is not just a set of metal and plastic things, I phone was someone’s dream, the concept of being able to communicate from far away.
It has been molded with the best shape possible to do what it does and has much different functionality that must work in sync to make a call possible.
Evans explains that the code should not be seen as files containing symbols.
It is more than that.
When beginning to code we should focus on what the main goal, dream, and purpose are.
What domain this does code need to operate in?
Once we fully understand that we can be sure to code the right thing and not introduce errors inside the codebase
When multiple teams work on the same codebase or, like in my case, when we deal with very old code that is easily breakable, specific care needs to be taken in not breaking what is working.
Delicate is not synonymous with broken and, chances are, something 10 years old has already made its way to become the core of the business.
A critical error during refactoring the session domain, customers, or orders, and a big chunk of the revenues can go away is a snap of the finger.
Bringing with them several people working within the company.
In my opinion, the domain is also this.
So, how do we preserve delicate code?
Anti Corruption Layer
The majority of applications out there have been developed without using proper separate models, if then often the model is cumbersome and confused.
Sometimes these models have been so integrated with the system that is better don’t touch them at all and keep them outside.
This is another challenge when working with legacy code.
An Anti-Corruption Layer is a layer (it can be a package, a class, or an entire system) that lives in between our client and the external application.
This layer has to be still considered a full part of the DDD architecture of the domain.
Its role is to be a translator between the two different domains
How do you implement it?
The Anti Corruption Layer should be seen as a service from the client model.
If considered a service it will be very easy to consume while laying in between the two.
The service will do the translation and our model remain insulated.
The way this layer is formed is by using a facade for each domain it is translating this facade then, in order to be consumed needs an adapter that can use it.
If, like in my case you have many different domains in your legacy code. you will need many facades that connect to it, also each facade needs to be ‘adapted’ with its own adapter to avoid clutter and multi-responsibility.