fear, loathing, legacy code

Fear and Loathing in Legacy Code

For people in leadership, legacy code typically has a fairly straightforward interpretation.  It’s the stuff in your application portfolio that you inherited.  And accordingly, it’s typically the stuff that you’d most like to sunset.

As I pointed out recently, this is a curious thing.  The word “legacy” generally has a positive connotation.  But in the IT world, we spin it on its head and use it almost as a curse.

Of course, while we may agree that it’s a dirty word, we don’t tend to agree on exactly what it means as I also pointed out in that post.  The typical IT leadership definition is in there: inherited code.  But so too are other definitions, including code written on obsolete platforms, code written without unit tests, and code that inspires fear.

And it’s that last definition that I’d like to focus on in this post, rather than the one about inheriting codebases.

The Legacy Code Problem From a Leadership Perspective

Why is legacy code an issue however we define it?  You’d probably offer responses talking about risk, high defect rates, and unpredictable deployments.  You might also talk about slow times to market and difficulty responding to changing business needs.

All of this is true.  But none of this, I would argue, poses the largest risk to your organization.

Instead, it’s the fear that poses the large risk.  Well not the fear itself, but rather the problems that the fear creates—the human problems.  The underlying human issues serve to exacerbate everything that I’ve already mentioned and create a whole host of other problems besides.

And worst of all, you might not understand that legacy code is creating misery within your group if you operate exclusively according to the “inherited from someone else” definition.  The developers in your group might be creating code, even as you read this, that inspires a fear of change.  And if they are, you have potentially big problems.

Now you can’t just walk up to them and ask if they’re afraid.  They’d probably just look at you strangely.  And likewise, you can’t really ask them, “do you have a legacy code problem?” since this would invite all manner of opinions and subjective definitions.

To identify this problem, you have to learn to recognize it indirectly.  And you do that by looking for the following organizational anti-patterns.

1. Fear of Touching the Code

As I said a moment ago, developers aren’t just going to tell you that they’re afraid of the code.  At least, not in those terms.  Receiving an assignment to make some changes and expressing fear to complete it risks their reputation.  “What kind of software developer is afraid to write and change code,” they’ll wonder.  Even if you’d want them to freely speak their mind, professional pride is at stake.

So look instead at indirect signs of fear.

First of all, look for elaborate explanations to avoid making changes.  Often, this will take the form of things that don’t seem to make sense.  The business wants the color of a button to change, and when you present this to the team, you hear a highly technical explanation of the application architecture’s entire history and why that makes button color changes difficult.  That might be a little extreme, but it gives you an idea.

Secondly, look for team members who try avoiding the work. When the button change request comes in, they point out that someone else was actually working in that area of the code more recently than you, so he’d be a better fit.

These are two of the most common reactions to this sort of fear that you’ll see, but there are others—more than we could cover here.  Generally speaking, look for anything that seems like disproportionate resistance to making changes to the code.

2. Loathing of Past or Current Team Members

Next, consider something less subtle.  I’m talking about loathing among the members of your team.  Or, if not outright loathing, at least signs of hostility.

If people on the team are passing the buck, you can get they’re also pointing fingers when issues crop up.  They’re probably also talking derisively at times about the quality of one another’s code or decision-making.  Generally speaking, look for bickering that the team may try (unsuccessfully) to hide from you.

Another way this shows itself is with cliques or divisions among the team.  Frequently, new team members will hold the established people responsible for the state of the code, fairly or unfairly.  The established team members, meanwhile, will get tired of the endless critical opinions of newbies who may often come in and unwittingly introduce bugs.  Of course, that’s just one example of the battle lines they could draw.  There may be others.

But to generalize, look for signs of infighting over the codebase.

3. Collective Embarrassment and Defensiveness

If you’re looking for something that the team can agree on, however, you’ll probably find it in how they feel about the codebase.  Specifically, you won’t see a lot of pride.

A lot of teams with healthy codebases point with pride to things they’ve done.  Perhaps it’s some design patterns that they’ve used or a particularly elegantly presented feature.  It’s human nature to take pride in one’s work.

But in a team dealing with a legacy codebase and the fear that it inspires, you won’t see that.  The team will frequently apologize for the state of the code or offer lengthy qualifying explanations and excuses.  You’ll hear things like, “yeah, that’s a work in progress, and we know it really shouldn’t look like that…”

And that’s if the team doesn’t become outright defensive and hostile when talking about code quality issues.  They might react angrily to QA pointing out defects found during testing or to project managers inquiring about the status of upcoming features. They might chew people out or lecture them for “asking for the impossible” when they make seemingly reasonable feature requests.

4. Low Engagement and Interest in the Tech

Fear of the codebase, mutual dislike, and embarrassment about their work leads to some predictable outcomes.  One of these predictable outcomes is that the team checks out mentally.

In a lot of organizations, the languages, frameworks, and tools that they use interest the team a lot.  Some of them may go to user groups, hackathons, and conferences in their spare time.  But whether they do this or not, they’ll often talk excitedly about new developments and features.  And they’ll also probably read blog posts and watch videos about these things.

In a team beset by legacy code, however, you’ll see a much different attitude.  The team members will want to have the absolute bare minimum amount of interaction with the codebase and anything related to it.  Water cooler conversations will focus on anything but technology.  And if someone does bring up a relevant professional topic, the rest of the team will likely roll their eyes and walk away.

Keep your eyes out for a widespread lack of engagement.

5. Turnover or Attrition Among Newer Staff

All of the previous steps add up to yet another predictable outcome.  The low morale causes people to leave.

Usually when you’re talking about a legacy codebase, your longest tenured people tend to have a stickier relationship with the company.  They’re used to the situation and will more often stay put.  Look for departures among newer employees.

What happens here is that they show up, get acclimated to what’s happening, and then they conclude relatively quickly that there are serious issues, both technically and culturally.  Some may look for a better job immediately.  Others might stay for a while, trying to make a difference.  But they’ll often give up after a while.

The end result?  A lot of companies with serious legacy codebase problems have a handful of long-tenured senior developers on-hand, but they can’t keep anyone else for very long.

Make a Plan to Reduce the Fear

As you can see, legacy code can present an insidious and pervasive problem.  Of course, legacy code doesn’t always create such extremes among software groups.  It tends to be a matter of degrees.  But if you’re noticing these signs from your team, there’s a pretty good chance you have a legacy code problem, whether you inherited the codebase or not.

Luckily, it’s a very fixable problem.  The first thing you need to do is to understand that you’re in a situation with heavy technical debt.  So you’ll need to help your team manage expectations accordingly and to dig out from under.  It’ll mean more time to get the codebase into less of a risky state.

Next, you need to start eliminating the risk.  Retire unneeded parts of the codebase, if possible, and identify the highest sources of risk and problems in the code.  Then immediately start getting that part of the codebase covered by unit tests so that you can set about fixing it.  Continue this pattern, chipping away, until the codebase becomes manageable for the team.

And remember that having a legacy codebase problem isn’t just an application portfolio management problem.  It’s a human problem that can cripple your organization.