Stories about Software


A Manager’s Guide to Legacy Code

Editorial Note: I originally wrote this post for the NDepend blog.  Go check out the original here, at their site.  If you like posts about static analysis, code quality, and architecture, head on over and check it out.

If you have a sadistic streak and manage a team of software developers, it’s probably high entertainment to dredge up some old, dusty piece of software and then to task them with maintaining it.  If, on the other hand, you’re a normal human being and you’re asking this because it’s necessary for your business, you brace yourself.  After all, this is legacy software, and the reaction of the team is likely to be quite predictable.

Alright, let’s take a look at this thing.  Oh, man, look at that right there.  A global variable.  And — oh my god — there are dozens of these things.  Who even wrote this?  And, look at this over here.  That’s the kind of idiotic, backward code that we used to have to write 20 years and 6 language versions ago when this code was current.  But even when it was current, this code was horrible.  This was obviously written by a trained ape.

When you’re a developer, the only thing worse and more contemptible than the uninformed code you wrote years ago, is the code that someone else wrote years ago.  Not only is it alien to you in makeup and reasoning, this legacy code also features patterns that have gone out of date or even been forgotten.


But lest you, as a manager, assume that this is simply a matter of developers being prima donnas, consider that an encounter with legacy code bother developers precisely because it renders them less effective.  They’re professionals, wanting to do good work, and the lead balloon you’ve dropped in their lap is an impediment to that.

Read More


Is There Value in Having Non-Technical People Do Code Review?

Editorial note: I originally wrote this post for the SmartBear blog.  Go to their site and check out the original!  If you like this post, there are a lot of good ones there by a variety of authors, on topics like code review, API design, testing, and more.

Here’s a thought exercise for you. Should non-technical people participate in code reviews?

It’s off the beaten path, to be sure, but I think it’s an interesting philosophical consideration. We’re entirely used to code review as an exercise by developers and for developers. But is there a place or purpose for outsiders to review our code?

Why do it?

I’ll state up front my answer to that question: “yes, provided it happens in a specific, directed way.” But to convince you, let me offer some potential benefits that I see, depending on who reviews what.

  • In general, it could bring members of the team with different skill sets closer together. Developers learn the business domain; why not let the business people understand the developers’ world?
  • This could serve as a sanity check. Are developers writing code that accurately reflects the domain?
  • It could also force developers to write code that is cleaner, more readable, and more maintainable. Imagine having to write code that a non-technical person might understand.

I’ll offer more detailed rationale for this thinking shortly.  But I imagine you’d agree that these goals would be worth pursuing.  If an occasional, different style of code review can help, then it’d be worth doing.

Be careful with this.


But before I talk about what these reviews might look like and how they could help, it’s important to stress that I’m not proposing a radical change to the code review process.  What I’m proposing is an occasional exercise to offer a different perspective on the team’s code.  Having non-technical folks look at the code shouldn’t be a vehicle for micromanagement or for former techies to quibble over code.  It shouldn’t be exhaustive, since a lot of plumbing code will be nonsense to them.

Read More


Why You Should Do Periodic Reviews of Legacy Code

Editorial Note: I originally wrote this post for the SmartBear blog.  Go take a look at the original here, at their site.  If you like posts about collaboration, code review, and other topics, take a look around while you’re there.

Legacy code is sort of like your house’s storage crawlspace.  It tends to be a repository for things that mattered to you in days past or on special occasions.  The code sits there, largely unnoticed, until such time as an odd change or a production bug causes you to dig it up, dust it off, and revisit it.  Barring extraordinary circumstances, it tends to sit, largely forgotten, and possibly rotting or getting riddled with moth holes.

By and large, this considered an acceptable and even desirable state of affairs in our industry.  A lot of folks that manage software development efforts and hold the purse strings think of software construction the way they think of building construction.  Once you’ve built a house, it’s done.  Why would you go back and revisit it unless there was some kind of problem that had cropped up?  The problem with this well-intentioned, bottom-line thinking is that building software isn’t much like building houses.

When you build software, you stack the new atop the old and everything comes along for the ride.  Sure, there may be the occasional new module that stands all by itself or plugs in with the rest, but that’s the exception.  The new code interacts with the old stuff, calling into it, relying on it, and running beside it in production.  If housing construction worked this way, a short circuit in the house across the street might cause your shower to stop working.

The result is that, however well-intentioned someone encouraging you not to focus on legacy code might be, the edict is often misguided.  If the short circuit across the street meant you couldn’t shower, would you listen to someone who told you their wiring was none of your business?  Clearly, you wouldn’t go storming over there out of nowhere, remodeling that house, but you wouldn’t just ignore it either.


This is the approach required with legacy code in your code base.  The fact that someone typed it out years ago doesn’t mean that it doesn’t have a very real, current impact on your team every time you deploy your code.  Because of this, it behooves you to review it occasionally, when time permits.

Let’s examine some specifics as to why it makes sense to audit your legacy code from time to time.  Having your finger on the pulse of everything going into production is a compelling but abstract argument.  So, let’s get more concrete.

Read More


Code Review Through the Years

What does a code review workflow look like, in your mind? Naturally, when I ask this question, you’re picturing life in 2015 with current tooling, work arrangements, and productivity tools. So when I say, “code review” you probably picture a whole lot more than peering at source code in some kind of file editor.

Maybe you’re imagining a multi-national, distributed, agile team working at different times of day. The team communicates using tools like Slack and various flavors of instant messenger (and, of course, the ubiquitous email). They no doubt use a sophisticated source control option, augmented with a variety of application management tools. Github comes to mind. And, that’s really just the start. Piggybacking on these capabilities for version controlling and communicating, the team probably employs relatively sophisticated heuristics for making sure all committed code gets a look from one or more other people, and they manage this complex communication with an equally sophisticated mechanism for allowing reviewers to zero in on exactly what has changed.

But perhaps the most beautiful thing about being a programmer in this day and age is that these impressive capabilities are pretty seamlessly managed. You can be sitting in London, where you make a series of simple, but cross-cutting, changes to a number of different source files. Then you can leave for the day, at which point a colleague in New York is notified that you have some changes to review. She can take a quick look, realize that the changes in which you’ve renamed a series of methods are extensive but low risk, and give you a thumbs up. She then kicks it over to another colleague in Los Angeles just for a quick second opinion, and delegates to him to make the final call. Once he takes a look and approves, there’s a mechanism to promote the code to a continuous integration environment, build it, run tests on it, and deploy it to production. Your changes are live the next morning when you come in.

We take this for granted, but, really, we’ve come a long way. Imagine what code reviews might have looked like in past eras of programming.


Read More


How Do You Know When to Touch Legacy Code?

Editorial Note: I originally wrote this post for the SmartBear blog.  Head over there and check out the original if you like it.  There’s a lot of good stuff over there worth a look.

Many situations in life seem to create no-win scenarios for you as you innocently go about your business. Here’s one that’s probably familiar to developers for whom pairing or code review is a standard part of the workflow.

You’re tasked with adding a bit of functionality to a long-lived, well-established code base. It’s your hope that new functionality means that you’re going to be writing purely new code, but, as you dig in, you realize you’re not that lucky. You need to open some Death Star of a method and make some edits.


The first thing that occurs to you while you’re in there is that the method is as messy as it is massive. So, you do a bit of cleanup, compacting some code, extracting some methods and generally abiding by the “Boy Scout Rule.” But when you submit for code review, a scandalized and outraged senior developer rushes over to your desk and demands to know if you’re insane. “Do you know how critical that method is!? One wrong move in there and you’ll take down the whole system!”

Yikes! Lesson learned. The next time you find yourself confronted by an ugly juggernaut, you’re careful to be downright surgical, only touching what is absolutely necessary. Of course, this time during code review, the senior developer takes you to task for not going the extra mile. “You know, that’s some pretty nasty code in there. Why didn’t you clean up a little as long as you were already in there?”

Frustrating, huh?

It’s hard to know when to touch existing code. This is especially true when it’s legacy code. Legacy is a term for which you might see any number of definitions. As a TDD practitioner, I personally like Michael Feathers’ definition of legacy code (from his book, Working Effectively with Legacy Code), which is “code without unit tests.”

But for the purposes of this post, let’s go with a more broadly relatable definition: legacy code is code that you’re afraid to touch. I’m sure you can relate to this, even if you’ve never had a senior developer yell at you about how touching it is dangerous (or better yet, leaving an all caps comment in the code threatening anyone who touches it). You size up a giant method with its dozens of locals, loops nested 5 deep, and global variable access galore, and think to yourself, “I have no idea what might happen if I change something here.”

So, what do you do? Should you touch it?

Read More