At Atomic Object, we work in a lot of existing codebases, editing code written by previous consultants, employees of the client organization, and sometimes even other Atomic developers. The older the codebase, the more inconsistency you’ll find in pattern, style, and organization. This, of course, makes jumping in to do additional work more difficult.
I want to do my part to keep this inconsistency to a minimum. Here are a few practices I’ve adopted to make my work clearer to future developers (and my future self).
1. Comments that Explain Decisions
In general, I prefer to keep comments to a minimum. Function declarations should speak for themselves about what they do and what their inputs and outputs are. Classes should have a clear responsibility. Tests should show how a program works.
However, when writing code that unknown future developers will have to deal with, I try to be much more liberal with comments. I still don’t write comments to say what a function does; that can become outdated as soon as the function is changed. Instead, I write comments to explain how decisions were made.
It’s not unusual to look at some code and think, “Why the #@*% did they do that?” I like to think my code is understandable to anyone. Still, I know there will be developers who look at my code and ask themselves the same question.
I use comments to answer any questions I might ask if I came across my work in the future. Why did I add this function? Why doesn’t this math look right at first glance? Why go through all this effort to avoid a more obvious solution?
The answers won’t always satisfy whoever asks the questions, but it’s better than letting a future developer waste their time trying to discover why I came to a solution one way instead of another.
2. Descriptive Commit Messages
Git history is immensely valuable for showing how code has changed over time. It’s generally a reliable resource for developers, even if a project changes hands multiple times.
Unfortunately, it’s easy to fall into a routine of writing unhelpful or nondescript commit messages. I usually justify them by trying to squash multiple commits into one, promising to write a more helpful commit later, or assuring myself that nobody else will have to touch what I’ve changed for a long time.
But commit messages need your attention; they’re some of a codebase’s most important documentation. Yes, you could just write: “Added button.” But it doesn’t take much more effort to write: “Added reset button to the settings page to let users discard pending changes.” And it will make a big difference to someone else looking through the git history long after you’ve touched anything.
3. Verbose Pull Requests
Just as a commit message is a useful way to summarize a small change, a pull request is a great way to summarize a large one. Pull requests are a record of when and how features were added to a codebase, helping future developers understand how a project has grown.
Descriptive pull requests tend to happen naturally with large teams, serving as a record of discussions and a review of feature work. But small or one-person teams can also take advantage of pull requests. I try to be verbose when writing them, using them to mark and describe major work I’ve done. This should be a big help to anyone trying to understand my work in the future.
It can be annoying to constantly explain your work through comments, commits, and pull requests. But remember what it’s like to explore an unfamiliar codebase or pick up a project you haven’t touched in a long time. Being able to understand why or how things were done can make that process much more manageable.
So the next time you’re in a codebase that will eventually be worked on by somebody else, try to be conscious of how you can help build that next person’s understanding.