title

The challenges of legacy code

  • user
    Juliette
  •  02.12.2021
  •  6 MIN

Legacy code is the “original” code present in websites or applications, but which has become obsolete or difficult to maintain. It is called legacy code because it is usually code inherited from another developer.

Developers are often afraid to “break” this code by modifying it, because the lack of automated tests at the time of its creation or its lack of documentation makes it fragile. Like a Jenga, modifying a piece of this code can lead to other malfunctions (sometimes quite random).

So how can we improve this code? Should it be fixed in spite of the business or the service that needs to continue? What are the recruitment issues related to too much legacy code? These are the questions we will try to answer thanks to Etienne Pinault, Mobile Team Lead at Sightcall, Jérémy Laplanche, CTO at Imparfaite and Gabriel Pillet, CTO at Web^ID.

 

“All code will become legacy”

“Having legacy code is not a failure, it proves that the application has been successful over time, despite the technical debt. In any case, any code, no matter how beautiful it is written today, will be the legacy of tomorrow. It is still important to come back regularly to refresh the code and progressively remove the technical debt” explains Gabriel Pillet, CTO at Web^ID.

 

Indeed, there are 3 types of legacy code:

  1. Code that has been looked after by its predecessors. It is clear, commented, tested and therefore easily maintainable (but this is not the most frequent case!).
  2. Code that is difficult to maintain. It is not very readable at first glance, it contains dead or duplicated code, there are classes that are too large, there are few or no unit tests, etc.
  3. Obsolete code. This is code that has not kept up with changes in the framework and/or language. With version changes, it has become difficult to add a feature and developers spend their time keeping the code afloat.

 

Disclaimer: In this article we will rather discuss the second type of legacy code. However, it is necessary to keep in mind that there is legacy code that is very clean.

 

It is rare, when we talk about legacy, that we refer to a perfectly clean code base. Indeed, in our daily exchanges with developers or CTOs for example, a negative connotation is almost always associated with the idea of legacy code.

 

Legacy code explained in a few words

The concept of legacy code can be understood quite easily: imagine it as the construction of a Lego.

You are faced with a Lego that was built years ago with parts that no longer exist today.

And then you are told: “you see this Lego construction, you have to correct all the parts that are no longer on their axis and above all we want it to be completely articulated in two days' time”.

Add to that the fact that the person or persons who built this Lego at the time are no longer around, that you don't have the construction manual and that it is impossible to get hold of it.

 

Have fun!

What does poorly maintained legacy code look like?

Now that we have the definition, let's take a look at what legacy code looks like:

 

  • It is not clear or readable,
  • There is dead or duplicated code,
  • There are few, if any, comments,
  • There are no explicit variable or class names (they are abbreviations that only your predecessor knew, etc.),
  • The classes are very large (5000~7000 lines),
  • The architecture is too complex and not mastered,

 

and above all: there are no unit tests!

 

If the code base of your application looks like this, then we can say that your project has a large technical debt. The problem is that the more technical debt you have, the more expensive it is to maintain.

 

What is technical debt?

The concept of technical debt appeared in the 1990s and allows us to analyse the durability and evolution of IT developments over time.

What are the causes of technical debt?

There can be many causes, but four explanations are most often at the origin of technical debt:

 

  • Lack of time. Your customers, or even the founders of your startup, want to see the developments as soon as possible, so the testing phase is forgotten in order to deliver the project on time. Indeed, the “time to market” issue is key for many startups launching a SaaS application, for various strategic reasons (to go faster than the competition, to have customers — and therefore revenues — quickly in order to raise funds and move to the scaling phase, etc.).

 

“As a CTO, having a “tech” vision of a project is essential, but even the most perfect project, if it is not in line with business expectations, will not work. You have to keep in mind that in order to evolve the service, it has to be “profitable”.

That's why in the first six months we did a lot of things that weren't very clean, but for the last nine to ten months everything we do is intended to be done more correctly. It's far from perfect, but as we go along, we're clearing up the technical debt and putting the right tools in place,” analyses Jérémy Laplanche, CTO at Imparfaite.

 

  • Lack of budget

 

  • The lack of skills of the developer who created the code. This means that the developer in charge may not have mastered good development practices enough to lay the foundations of the code.

 

“At Imparfaite, what happened was that the team was made up of people who came in from time to time and left. So they were given an assignment, they did it, but they didn't necessarily look closely at the output. It worked, so much the better. Except that as time went on, we found ourselves with a pile of bad code on the project to the point that when I arrived, we were on the verge of the whole code breaking” explains Jérémy Laplanche.

 

  • The development team is too small. There are not enough developers and everyone is working on the project's evolutions, putting the improvement and evolution of the existing code on the back burner.

 

What problems arise when the legacy code is too large for a company?

  • Security issues: this particularly affects banks and financial services. This is what happened in 2017 to Equifax, a credit rating company.

The Equifax’s story

In 2017, one of the world's largest credit rating agencies, Equifax, suffered an attack by hackers who had used a security hole in the company's computer system to their advantage. The data of 148 million people worldwide was compromised.

However, a report by the Government Accountability Office in the United States concluded that the breach was entirely preventable and was partly caused by legacy code on the website that dated back to the 1970s...

In addition to the clean-up costs, which have been estimated at $1.3 billion, security breaches have a major influence on the confidence of your consumers and the public.

 

  • Financial issues

Too much technical debt can cost a lot in maintenance and refactoring. Refactoring is the act of going back over the code base to clarify, debug and clean it up: this has a cost since an internal or outsourced human resource must commit time to such a technical subject.

As mentioned above, in order to respect the delivery time constraints of a project, the code is developed in a functional but technically imperfect manner: this almost necessarily implies a code rework or refactoring phase in the long term.

According to a study by the Consortium for IT Software Quality, legacy systems cost American companies $70 billion in 2003, compared with $596 billion in 2018.

 

  • Time issues

Refactoring (i.e. cleaning up code without changing its behaviour) takes hours and is often placed at the bottom of the task list. In fact, only between 11% and 30% of development time is allocated to technical debt in companies. Of this time spent, studies have shown that about 50% of the time spent maintaining code is actually spent trying to understand the code they are trying to maintain!

 

  • Recruitment issues

We can attest to the fact that the presence of significant technical debt is a real barrier to the recruitment of new tech talent. Depending on the state of the legacy code, recruitment is not impossible, but it is more complex. The mistake to avoid is not to mention the reality of the legacy code during recruitment interviews, because this is the best way to ensure that a developer is disappointed and considers leaving the job in the short term.

 

To alleviate the difficulty of recruiting with a large technical debt, it is better to be transparent about the real state of your code, or even to show it during the recruitment interviews. In this way, you ensure that you only recruit profiles who join your project with full knowledge of the facts and who have the desire (or even experience on the subject) to take part in a code improvement and refactoring phase.

 

“A code that is too legacy with a high technical debt can put off new candidates for hiring, who are often looking for projects with modern, state-of-the-art technologies. It is therefore more difficult to recruit when the technologies used are too late and no longer current.” explains Gabriel Pillet, CTO of Web^ID.

 

Even if tackling a large legacy project can put off junior profiles, this type of project can, on the other hand, offer a great challenge to experienced developers.

 

“Some senior profiles are happy to be confronted with the problems of refactoring legacy projects, limiting technical debt, improving quality and stabilizing the code often offers more challenge than starting a project from scratch,” says Gabriel Pillet.

 

But why not focus on constantly improving legacy code if it has so many drawbacks?

Simply because it means taking the risk of cutting a service that works.

If the original developer understands his code de facto, this may not be the case for other and future team members if the code does not respect development best practices.

Moreover, over the years, the team evolves and the code becomes a real patchwork that is increasingly difficult to understand and modify. Until it becomes impossible to make updates or changes because no one understands the code and its effects anymore.

 

"A legacy code, even if it is technically indebted, you don't touch it. If it works, we let it work and there is no reason to change anything. That's why taking an application from scratch doesn't make sense, because the service will work the same, it will just be better written; but that in itself is irrelevant.

If there's a feature or a piece of code that doesn't work or that you need to change for product reasons, then you can change it. But in general, as long as it works, we don't touch it, because we risk breaking everything for not very much," explains Etienne Pinault, Mobile Team Leader at Sightcall.

 

Jérémy Laplanche, CTO at Imparfaite, explains that "you have to know how to juggle two aspects of development: the technical aspect and the business. For a CTO, it is necessary to know where you can afford to add technical debt with commentary, tests, etc., while ensuring that you don't break anything as you go along. The most important thing is to keep in mind that we will never achieve zero technical debt, what we need to do is limit it as much as possible.

 

Good practices and solutions

In order to avoid technical debt, it is necessary to start by putting in place good development practices.

These include

 

  • Putting in place clear documentation,
  • Agreeing with the rest of the team on a methodology to follow,
  • Using a framework,

 

“In the audits we carry out, we find that the use of a framework greatly limits drift, whereas "home-made" code is almost always linked to a large technical debt and leads to having to redo a new version of the application,” says Gabriel Pillet, CTO of Web^ID.  

 

  • Do some tests! Before or after, but testing your code remains an important step that avoids many pitfalls. You can use the TDD (Test Driven Development) method, i.e. develop your digital service little by little by writing a test before the code.

 

Why is it better to create tests before the code?

Quite simply, because if you tell yourself that you'll end up testing once the code is written, there's a good chance you'll never do it. Typically, the testing stage is relegated to the end of your to-do list and, in the end, this stage is often reduced or even eliminated due to lack of time.

 

If you are already facing a large technical debt, what are your options?

 

  • Refactoring, i.e. reworking the code to improve its readability, understanding, quality, architecture or performance. By renaming classes, creating new layers, etc. in order to restructure the code without changing its final function.

 

“The good idea is to refactor in small chunks, and have it introduced by a new feature. That's the best thing to do in my opinion, because you're going to satisfy both the business by introducing a new feature that will be useful to them, and the development team, because you're going to reduce some of the technical debt. You can't reduce technical debt just to reduce it, there has to be something else to go with it,” explains Etienne Pinault, Mobile Team Lead at Sightcall.

 

  • Go through an agency. If you don't have the time, or the in-house skills, to do a redesign, there are specialist companies that can help you restructure your code.

 

In short, you can't avoid legacy code, so the best thing to do is to be patient and technical!

Find your dream job

This site uses cookies and gives you control over what you want to activate.