Write What You Know
One of the distinguishing features of Big Nerd Ranch is a focus on recording knowledge. On our projects, we write down what we know, and we’ve found that recording knowledge is an essential way to help ourselves and our teammates keep up with the constant change of software development projects. Let’s talk about the ways I’ve seen knowledge recorded and how doing so solves these problems.
How We Record Knowledge
Every project is different, but in general, I’ve seen knowledge recorded in these ways on BNR projects:
- The README. We make sure there is a README file in the code repository that records essential information, such as how to get the app running, how to run its tests, how it authenticates to external systems, where it is deployed, and other essentials. When we discover a necessary bit of information that wasn’t in the README, we add it. When we see that some information is out-of-date, we correct it. When we see that something in the README hasn’t turned out to be useful, we remove it. A README that is focused, thorough, and accurate helps us to efficiently onboard new developers and get the codebase running on new machines. And every time we onboard someone it’s a chance to test the instructions in the README and make any necessary updates.
- Up-to-date story descriptions. When a story is clarified, changed, split, or combined, we update that story’s description in our project management tool. This ensures that all team members who need to work with that story have the latest information on what is and isn’t included. The story comment thread may track the discussion of the changes, but the story description is the authoritative current state.
- Conversations in public chat channels. For project communications we tend to avoid direct messages, preferring discussions in public Slack channels. This gives others the option to follow along, chime in, or refer back to the conversation in the future. And “public” channels doesn’t just mean public to BNR, but public to our client team as well. This gets that information to our clients gives them visibility into our work, and provides us another layer of accountability.
- Architecture decision records. When we are assessing a technical decision that has tradeoffs, we often record the result in an architecture decision record. This write-up includes the need, options, evaluation criteria, and the ultimate decision. This way, if the decision needs to be revisited in the future, the thought process is available for reassessment.
- Commit messages and pull request descriptions. We do our work in small, focused commits, and we take the time to describe what they are doing accurately. We use pull requests (PRs) that include a description that covers the work, decisions made, and its relationship to other units of work. We link the PR to the relevant story in our project management tool. We do code review in comment conversations in the PR. All of this allows developers in the future to understand why a change to the code was made.
- Updating the code. Our goal is to have code that clearly communicates what it does. When the code has become difficult to understand or misleading, we update it to communicate more clearly. This can involve removing dead code, making names more precise and accurate, and making sure any comments are correct and useful.
Why do we record the knowledge in so many different places? In large part, it’s to keep the information close to where it will be the most useful and easily discoverable. For example, instead of writing a wiki page to describe getting the codebase running, we record that in a README file in the codebase itself, where a developer can easily find it. Instead of explaining hard-to-understand code with comments, first, we look to see if we can make the code itself easier to understand. Instead of keeping changes to a story’s scope in a Slack thread, we update the story’s description, so that anyone who reads the story will see the updated scope right away.
Why We Record Knowledge
Recording knowledge in all the above ways sounds like it could be a lot of work! Why do we think it’s a good use of our time? As I looked into our motivation, three themes, or beliefs, emerged. The more strongly you believe the following three ideas, the more it makes sense to invest in recording knowledge.
1. The code will change.
If we knew the code would never need to change because of bugs or new requirements, then recording knowledge of the system wouldn’t matter much. The system could be treated as a black box that gives you the result you want. There are some systems for which that’s true, they are simple enough or in a fixed-enough domain that they really don’t need to change (although keep in mind that the technical environment they’re in does occasionally need to change).
For most business and consumer applications, new requirements come in regularly. We will need to make changes and introduce new or fixed functionality in a cost-efficient manner while preserving existing functionality. To do this, we need to understand the system well. We invest in recording knowledge as we go, confident that that investment will pay off in improved ability to make changes in the future. If we skip this investment we might get stuck with a system we can’t understand, and therefore that we can’t enhance without breaking it in surprising ways.
2. Our capacity is limited.
Recording the team’s knowledge never feels urgent, because the team already understands the system now. But that doesn’t mean we’ll understand it later. It’s easy to forget what we know, especially as the system grows and as we move between different projects. Humans have finite mental capacity, so we shouldn’t expect ourselves to have a perfect memory or beat ourselves up when we don’t. Instead, we should help ourselves out by recording our knowledge for the future.
In the book Refactoring, here’s how Martin Fowler describes the process of recording knowledge, specifically by recording it in the code (emphasis mine):
At that point I have some understanding [of the code] in my head, but my head isn’t a very good record of such details. As Ward Cunningham puts it, by refactoring I move the understanding from my head into the code itself…If I move my understanding into the code, it will be preserved longer and be visible to my colleagues.
3. We should look out for one another.
I understand the code, but I’m not the only one who will need to. The team will grow, or I’ll be swapped onto a different project, or go on vacation, or win the lottery and leave the company. It’s especially frequent for us consultants to experience personnel changes because we usually won’t be working on the same system indefinitely. Someday another BNR Nerd or client developer will take my place.
Why don’t I always record knowledge for these future developers? Sometimes the thought just doesn’t occur to me, or I underestimate how hard my code is to understand. But other times it can be tempting to say “I had to work hard to learn this code, so it’s okay if others have to work hard too.”
That’s not the way we want to act toward our fellow developers. Collaboration means we should work together for the success of the project. And as fellow developers and humans, we should be looking for ways to help each other out. Software development has been one of the most explosively growing industries over the last few decades and demand almost always exceeds available developers, so it’s not as if we are competing for scarce opportunities. In fact, I would say we have a professional responsibility to help other developers level up to meet the development needs that no one individual or consultancy can meet.
Help Me, Help You
Recording knowledge is a mutually beneficial activity. Writing down my own understanding helps me verify and clarify it. It helps code reviewers confirm that it’s the best approach. It helps me in a few weeks when I’ve forgotten how something works or why we made a decision. And it helps future developers next month and next year who onboard onto the team and have to get up to speed.
If you recognize that your code will continuously change, that your human capacity is limited, and that you have a responsibility toward other developers, then recording your knowledge will help. The techniques described above will support you and others through that ongoing change.