As a software developer, unless you somehow landed a dream job where you work on nothing but greenfield projects (brand new projects where you can write fresh new source code), you will most likely end up dealing with legacy code.
When I say legacy code, I mean source code that’s really been around the block. Not just code that was written maybe a few weeks or months ago. Code that’s been around for 5 years. 10 years. 20 years.
This may be hard to believe but it’s no uncommon to see source code that’s been around for 30 years or more!
One of the more famous examples of legacy code that’s still alive and well is the source code running NASA’s Voyager 1 & 2 exploration spacecraft. Voyager 1 launched from Earth back in September 5, 1977.
That’s code that’s almost FORTY YEARS OLD! And barring any unforeseen disasters, it will continue to run and hum along inside of Voyager 1 well into the 21st century and beyond. (Maybe even long enough for Captain Kirk to intercept it in Federation space!)
There are some unique challenges dealing with legacy code bases.
I divide the challenges into two main categories
- The people problem
- The technical
Going back to the Voyager 1 example, the last original computer programmer from the Voyager 1 project, announced his official retirement from NASA sometime this year.
It underlies a classic problem that doesn’t really have a solution.
The problem revolves around the nature of computer code. Computer code doesn’t age in the physical sense.
We humans age. As we get older in life, our bodies start deteriorating, both physically and mentally. We can’t run as fast we used to as teenagers. We can’t learn as fast as we were when we were kids. Sad, but it’s a fact of life.
Computer code doesn’t have that problem. As long as the hardware and infrastructure that the code runs on is in working condition, that computer code will continue to run until kingdom come.
In fact, the Voyager 1 code is proving it’s outlasting the humans that originally designed it.
As the number of people who know the original system retire, leave a company/organization, etc.., the larger the support problem becomes.
There will soon be nobody at NASA who will know how the original system worked.
Some people may balk at this situation. So what, you can find a programmer anywhere on the planet! Just find another programmer to take over!
Here’s the problem with that.
Computer programmers, as a whole, gravitate to new technology and fresh greenfield projects. Ask any fresh computer science college graduate what they want to do in their first programming gig, and it’s a safe bet to conclude the last thing they want to work on is old, ancient legacy code.
One, for the simple fact that on the whole, you want to build your software engineering career on knowing current and new technology. That’s what companies are looking for skillswise … simple supply and demand.
Sure, if you know Cobol during the whole Y2K bug crisis, you could have charged exorbitant consulting fees to companies desperate to fix their Cobol codebase, because the younger generation of programmer neither possessed, nor desired to work on Cobol codebases.
But those kind of situations aren’t something you can predict. If you were lucky enough to have known Cobol, pre-Y2K, and were in the right place at the right time, you could have taken advantage of that situation.
But you can’t predict those kinds of things. The better odds, as a software developer is to make sure you build a career on technology that is either fairly recent or new technology that you know will stick around for the foreseeable future.
The next best thing that NASA can hope for is dig through their personnel ranks, and see if they can find someone who was there during the original years of the Voyager program, but younger than the original programmers…perhaps an intern who was part of the project at the time.
The other major problem is the actual legacy technology.
Modern programming languages benefit from all the lessons learned from older computer language as well as new trends in computer science. Way back when computer systems were first introduced in the 1950s, the only way you could program a computer was in its native
“tongue”, binary code … that is, 1s and 0s .
Even to this day, computers ultimately understand only 1s and 0s.
Try writing an entire computer program in 1s and 0s! Believe it or not, in the early days of computer programming, programmers had no choice but to write code this way.
But humans don’t think in terms of 1s and 0s.
We think at a higher abstraction than computers.
It wasn’t long before some clever programmers created more human like languages to interact with computers.
Software applications called “compilers” would translate computer languages invented by humans, into the native 1s and 0s of binary language.
Assembly language was easier to read than binary code … not by much, but hey, it was a start!
Other languages soon followed after that. Languages like Basic. C. C++. Objective-C.
As the computer languages evolved, they introduced functionality and concept that helped computer programmers make their jobs easier.
Things like functions, which the C language introduced, and helped programmers break down big computer programs into more digestible and readable code.
The C++ language introduced a big programming paradigm shift called “Object oriented programming”. Object oriented programming allows a software developer to break down project requirements into something that humans naturally are able to analyze and process…objects.
Other concepts like test driven development and agile/scrum methodologies came into existence to help create higher quality code with less bugs and faster delivery to customers.
Recently, my team went through a significant reorg and we suddenly became the carekeepers of a key piece of one of the original legacy systems which our entire company still makes significant revenue from.
When I say legacy system, I’m not kidding. It uses a very old version of the Basic computer language called Pick Basic and our team has recently been reviewing codebases that go back all the way to the 1980s!
For the past week and change, my team has been doing nothing but code reviewing the specific pieces of legacy code relevant for our project, which is to make some key enhancements to this.
We are trying to mitigate the loss of important subject matter experts who have either volunteered to retire, leave the company or been the subject of company wide layoffs, and who were the primary developers of this legacy system.
The fewer people who know a legacy system, the more dangerous a support situation you create for yourself.
Now in NASA’s case, yes, they are experiencing a similar problem. But worst case scenario, if NASA can’t find any more software engineers who know how the Voyager 1 code works, well, they cross their fingers, and hope the spacecraft continues its voyage into interstellar space.
But it worst case scenario happens and the Voyager 1 spacecraft fails, well, life goes on and NASA continues to work on newer projects.
In our case, our situation is a little different. Our legacy system, the bedrock of pretty much every other modern system our company operates, simply can’t just “go away”.
That happens, and our company’s primary technology layer causes unwanted rippling effects in accounting, HR, sales, marketing, pretty much every division of our company, which relies on data from this legacy system.
Our company can’t afford to let their legacy system break down or go unsupported…there’s simply too many “hooks” by other critical systems.
The challenges of dealing with legacy code are twofold
- Understanding the business domain
- Understanding the legacy language
Of the two challenges, I would say that the first challenge, the understanding of the business domain is the more challenging.
Any seasoned software developer, worth their salt, can pretty much read any kind of source code and glean at least a general intention and understanding of what the code is trying to do.
Understanding the business domain behind the legacy code, is really the crucial piece behind successfully understanding and working with a legacy codebase.
Without a clear understanding behind the business processes which the legacy code is designed against, it will be impossible to figure out what happens when a new production defect/bug happens.
Without understanding what a certain piece of code is supposed to accomplish from a business domain standpoint, there is no possible way a software developer will be able to fix the defect.
Sure, you can pick up the legacy programming language syntax, but say the defect revolves around dealing with an accounting general ledger system … if the software developer has no idea about how the accounting system is used by the company, there’s no amount of technical knowledge that will help them understand HOW to fix the problem.
That’s where you need a SME, or subject matter expert, who understands the business domain of a company and the specific business processes of the legacy system.
Our team has been lucky to have a team member who was one of the early and original developers of this legacy system. He possesses not only the technical knowledge required of the Pick Basic programming language, but more importantly, the business domain knowledge behind the legacy system.
As a team, we’re essentially “knowledge transferring” his business domain expertise for the specific project enhancement we’ve been assigned.
Essentially, we’re “spreading the wealth”, so to speak, so we don’t end up in the dangerous situation of one lone person who knows the legacy system.
This is all well and good, and this is the smart move to make.
But even if we’re successful at knowledge sharing our legacy system, sooner or later, we’re going to run into that human problem we covered earlier.
I’m getting older, the other members of our team are aging as well, and our company will have an extremely difficult time finding any new “young blood” who know how, let alone, DESIRE to learn a legacy system.
The company will, sooner or later, have to address the elephant in the room, that is the unsustainable legacy system that, they’ve successfully been able to keep going for the past 35+ years.
But the day of reckoning is coming. When the last developer of the original system either retires or leaves the company, the last thing the company can afford is to do nothing.
There will come a time when they will have to bite the bullet and make preparations and plans to completely replace their core legacy systems with something modern and sustainable … there’s just only so much duct tape and bailing wire in a software developer’s toolbox to keep an old system up and running.
As a developer, looking at ancient code bases, you almost feel like a digital archaeologist, like Indiana Jones, digging through layers and layers of old source code cruft and marveling at how the “old timers” were able to get a behemoth old legacy system up and running.
Going through the Pick basic code base, I marvel at the lack of modern programming language conventions that we take for granted these days … like object oriented programming, encapsulation, rich and useful external libraries and APIs that keep us from “reinventing the wheel”.
Not to mention the disposal of the internet at your fingertips to answer any technical question you may have.
Do I pine for the “good old days” of programming?
Thank you, no.
The past is a nice place to visit, but I’ll take my modern programming languages and software development methodologies, thank you very much.
Besides, I don’t think I’d look very good in bell bottoms and disco platform shoes.