“No matter how hard the past, you can always begin again” – Buddha
In my work environment, we have a portfolio which consists of a large amount of older code bases for which the team members are responsible to support for the business. I have personally experienced in the past the difficulties of supporting a legacy (I’ll use that term here but actually believe any product that starts it’s lifecycle from stabilization becomes legacy) applications and see how it can be a struggle for team members that I lead today.
Older technologies, poor implementations, no real guidance or design patterns, etc. Sometimes it is a real mess. I recall one of my mentors in development relaying to me when I was learning early in my career that fixing a problem in legacy code is often like donning a pith helmet and traipsing through a dense jungle. At the time, some of things I encountered used to make me so angry at why a developer might do some of the things he did in the implementation and it often caused massive refactoring (with care) to make it more maintainable. But as I matured as a technical worker, I began to realize a few base things:
- The developer may have been unequal to the task put before him. He may have been asked to do something for which his skill level made him unequipped to actually do and he created this in the best and most logical way he saw fit to accomplish his job. Maybe that popular “off the shelf” program did not exist when it was built.
- I believe that no developer sets out with the approach “I am going to write the sible code I can create”.
- The tools and technologies (or the depth of knowledge of them) at his disposal may have not allowed him to understand some of the side effects of things done.
- Maybe they did not have any real code standards or design patterns under which they were expected to write code.
- Refactoring of code is a given. Any code that exists and extended is likely to need refactoring when changed. Nothing is perfect.
- Bugs exist in the world. There are no perfect systems and any complex system will likely have issues that are unaccounted.
- If deep dependencies are used (3rd party or other systems) it is likely the developer though in terms of the environment of the day, not that the code might outlive those dependencies or they might change before this code base did so.
- Even if it is “legacy code”, as the current developer or team doing that job today, you assume ownership. You may not like the way it is written or find it difficult but the base fact is that you have taken on this code base as a part of your job.
- You are in control of refactoring and can, whenever possible, make things better for those who come after you.
- Instead of focusing on the negative aspects of the code base, why not (as a developer reminded me recently) utilize the boy scout motto and “leave it better than you found it”.
Actual Problems with older code bases
I know as a technical professional we all hate inheriting a messy or poorly designed code base. It really sucks to have to work on it, fix it and sometimes just keep it running as the technical world changes around it. I often describe some as neighborhoods in which I try and perform the least amount of interaction and then get out.
I also know that many organizations do not fully grasp the need of the “care and feeding” of code bases or the deeper understanding that software should have a lifecycle and die and be reborn or transformed. Many organizations I have been a part of would rather hear the “thump, thump, thump” of the old reliable software and not think about what happens if it becomes in a critical state.
“If it ain’t broke, don’t fix it” is a very common idea. I actually knew a major software company that ran it’s accounting and payroll from a mainframe Cobol code base long past it’s prime and even hired high dollar consultants long term to ensure it kept running each time it sputtered and dropped a dump in hexadecimal code.
But the cost of continuing to gamble on these large complex systems is risk and if understood by the organization, they would see the importance to mitigate that risk as they would any other risk to the business.
It’s like driving a 1965 Chevy Bel-Air car. As time goes by, maintenance becomes more pervasive, parts become more difficult to find and eventually you may not even be able to get them or need to have them custom machined to keep your car running. This car may be something you keep covered in the garage and drive only on Sundays when the weather is nice. But if like a core business system, you used this classic car for your daily commute, the expense of upkeep and the risk of failure become greater and greater as time wears on.
So what do I do? I am a little scared now …
You basically have 2 core options:
- Bite the bullet and replace the system in total or find a way to “cage and lifecycle”
- Use a legacy transition pattern to migrate the system to a more maintainable code base in the future.
- Cross your fingers and hope for the best.
Replacing a large complex core organizational code base is expensive. It is a large scale investment by a company and may require a significant technical and personnel investment to replace. This is a fact.
But, just like buying a home, it is also an investment that hopefully returns greater end results through actually taking time to ensure that the system still actually supports the business and does not have “dead zones” of features that people cared about or wanted 20 years ago but no longer need. It gives you an opportunity to think about how a system models to the current business. And even while recreating the system, you still must maintain the current system and managing the changes to that system can be a challenge.
You also could encounter the dreaded problem of “thinking in the old system” as opposed to thinking in terms of how the business works. This can be especially true when a system has been a core system. People stop thinking about what the business needs and relate it to more of what they currently have to maintain in the system . This can be especially risky in disaster recovery scenarios in which the business must know how to function without a system being in place. For many businesses, they never consider this issue (given the world of distributed servers and cold site switchover).
In short, if you take this route, the organization has to be focused and it may be painful but the goal is to create something (hopefully in a better designed way) that can be cared for over time and change over time. If you take this route, placing a lifecycle for the system is probably important as well.
One pattern I have become very interested in comes from Martin Fowler. It is called the “Strangler Pattern“. I find this approach very interesting as it balances the replacement of the former system with the new system but utilizes a common set of services to supply both until the legacy system is “strangled out”. The idea coming from vine growth in Fig trees that Fowler and his wife learned about on vacation. The vines sprout in the top portions of the tree and grow and eventually take over and replace the host.
I am not deeply versed on replacement patterns but my assumption is that this is only one of many. If you are fortunate enough to have an application that did use an MVC pattern, you might be able to begin to replace pieces in place and minimize disruption.
Another approach might be to leave the data structure as is (although legacy systems are often rife with business logic in the data tier), build the new system on an MVC or MVVM pattern with a services layer and later refactor the data tier over time and adjust the models to utilize the new data source while moving the business logic in a more desirable tier of the pattern.
As surprising as it sounds, this is actually a path that some folks take. Please don’t find yourself in this situation as all of the hope and good karma in the world is not going to pull your backside out of the fire when (and I say this as opposed to “if”) things go South.
I started this post as I think it is important as team members that have legacy application to understand just as we collective own the new code we create, we own the code that came before us as part of what we do. I think that it is important for organizations to understand that these code bases can equate to risk and should be mitigated as any other potential impact to the business and that there are many ways that we as technical and creative people can help move the needle forward.
And most of all, the statement given to me by that developer on a team that said “leave it better than you found it“(the Boy Scout motto).
I think that is sound advice, no matter what you do in your organization and should drive us all …