We all dream of a perfect, unencumbered world, working with a pristine code base or starting a project from scratch. In reality, I’ve started enough projects to know that I can build myself into a corner just as well as anyone else can, and that things always get messy unless you spend an incredible amount of time refactoring. I’d like to offer some advice about taking over someone else's code based on my experience: Keep your code teardowns to yourself. I learned this the hard way.
There was once some outrageously wrong code in one of HubSpot’s tools pummeling our services, and I jokingly started a witch hunt to figure out who had done it. It got to the point where people would ask me every morning “Did you find out who did it yet?” After a few days of digging I started to get a sinking feeling: I actually may have been the offender. Once I confirmed my own involvement I tried to just let it slide (“Uh, we’re still talking about this?”), but sensing my deflection, the team’s questions only increased in fervor. I eventually fessed up and felt like a total idiot, both for the mistake and for making a big deal out of it.
One thing that has felt almost universal to me as I’ve passed projects on to new owners, or picked up where some other team left off, is that the initial reactions are almost always too harsh. It’s very easy to be a critic, especially of someone else’s code (or even your own). Maybe we think of it as a rite of passage when we talk shit about a code base, but it can alienate the former team and is only a useful mindset if it pushes you to worthwhile action. It can also be poisonous for your team members and shift their perspectives to pessimism. Overall we should assume best intent and try to look at things optimistically. Finding a problem or bug in someone’s system shouldn’t be met with “Wow, how could we let this happen :sadpanda:?“, it should be “Wow, I’m glad I was able to spot and fix that issue.”
There are two possibilities to consider next time you take over someone else’s code: The code has legitimate structural issues, logic errors, and bugs (and you should just fix them), or you’re suffering from some sort of Dunning-Kruger effect where you don’t know enough to be accurately critical.
It’s overwhelmingly likely that the team or person who wrote the code did so in a different context than the one you’re in today. They probably saw less of the problem than you do now: You may have the advantage of looking at a working or complete system with the full set of requirements fleshed out. It’s also likely they had a different set of constraints. Maybe they were operating with a smaller team, different requirements altogether, or were rushing to market. Sometimes at HubSpot we ship something and intend to iterate on it, but admittedly never get around to it. In other words, they may have been intentionally optimizing for speed over quality at the time.
On the other hand, spotting issues and leveraging your new perspective can be helpful if it results in valuable improvements. I think it’s important that we don’t lose sight of leaving things in a better state than when we found them. You may even find that digging in and attempting to fix or improve code leads you down a path of understanding why things are the way they are in the first place. Personally, I’ve started large refactoring efforts a few times only to have it fall apart last minute because I’d missed some critical constraint.
You’ll likely be spending a good part of your career working with code that someone else originally wrote. You might as well accept that it won’t always make immediate sense or look great. To that end, two critical skills are learning to become comfortable making changes when you don’t understand the whole codebase, and knowing what changes would be valuable. Don’t be intimidated by a code base that you’re unfamiliar with — my recommendation is to dig in, focus on how you can test or verify what you’re doing, and start making small changes. It always feels daunting at first, but seeing the system behave differently in even the most minor way after a change you made can be invigorating.
I’ll leave you with two action items that I try to remember when inheriting code:
Embrace strange code and spend time where it is most valuable — digging in and making changes that help your customers or users — not WTFing.