Introspection at every step
In general, I don’t have much software engineering advice to give that doesn’t effectively boil down to “when writing or changing code, think about how it affects other people.” However, there’s a particular flavor of that statement that I’ve taken to repeating of late:
Introduce introspection to your workflow at every step
By “introspection,” I mean asking yourself some version of the following questions:
- Why am I making this change?
- Can I improve the impact of this change on our users?
- Can I make this change easier to review?
- Can I make it easier for the next person who will change this code?
Asking these questions even just once during your workflow can dramatically improve the quality and empathy of your work. But asking it multiple times—as often as possible, really—is what can separate good from great code.
As engineers, one of the ways that we avoid asking these questions is by thinking that writing code is the most important thing that we do. Too often, as soon as we “finish” coding a task in our editors, we rush through the process of staging our work, committing it, opening a pull request, and deploying it.
Instead, we should treat every part of our job that isn’t writing code as opportunities for introspection and improvement—especially those humdrum tasks that we often perform on autopilot.
View a diff of your changes in your editor
Take advantage of pauses in your work to view a diff of your changes, without leaving your editor. Most editors have plugins that produce a side-by-side diff of the currently open file. To name a few: vim-fugitive for Vim, split-diff for Atom, and DiffView for Sublime Text. This functionality is blessedly built-in to Visual Studio Code: Command+Shift+G.
A side-by-side, in-editor diff is a great opportunity for introspection since it functions as a preview of your future pull request. I also use a “git gutter” plugin to show indicators of where code has been deleted, inserted, or modified. (Some find this distracting, but I find it reminds me to open the side-by-side diff.)
Always use git add –patch
If I had to recommend one piece of advice from this post above all else, it would be this: Always use git add --patch
when staging your changes. (I use a git alias to help enforce this.)
Patch mode breaks your changes into chunks and asks you one by one if you’d like to stage them. It may sound tedious at first, but it’s perfect for introspection and often leads to insightful revisions and improvements. It also allows you to selectively stage code, which is great for opening incremental pull requests for big features.
To put this another way, running git add .
is an awful way to stage your changes. Are you the person on your team who is constantly opening PRs that contain debugging code like console.log? Don’t be that person.
Use an editor to write your commit messages
Writing your commit messages on the command line (git commit -m "i changed stuff"
) may seem like a nice shortcut, but it inevitably leads to shorter, less informative messages. Set your EDITOR, type git commit
, and write your message from the comfort of your editor. Git will also provide a summary of the changes you made in the comments below your cursor, which will help you write better messages.
Review your PR before opening it
We all know the merits of detailed PRs that provide tons of context (and PR templates that help with that). But after writing up that beautiful PR, take a second before clicking the button to open it. This is your last chance to think about your fellow team members before they take time out of their day to review your code.
GitHub helpfully provides a diff of your changes on this page—just scroll down. More often than I care to admit, this is the moment when something finally clicks for me and a better solution pops into my head. It’s also when I see where additional comments would really help out my reviewer.
Don’t try to automate introspection
Linting and testing are immensely valuable, but neither are a substitute for reviewing your own code as often as possible and asking yourself the important questions above. Resist the temptation of thinking that you can automate introspection or avoid it with more code.
Instead, I embrace the fact that I have two distinct modes as an engineer: writing code and finding ways to improve my code. It’s exceedingly rare that I can do both at once. Finding ways to switch between those two modes is the best way I’ve found to help myself and my team.