- Make every deliverable maintainable by someone else on your team
- Deliver small bits of maintainable work often
- Anything that is not maintainable should be considered debt or of no value
- Approach the maintenance of your deliverables with the same empathy as any other product
In software development, an important (if morbid) metric for organizational resilience is the “Bus Factor” of a project or product. In short, the bus factor of a project is how many developers would have to be hit by a bus for the project to fail. Of course the bus factor is applicable to many other parts of business outside of software development. My background however is primarily in software development, so this article will focus on that, but perhaps you can glean some general principles to apply elsewhere. Also, please don’t get hung up on the horrific bus scenario. There are many less dramatic (and traumatic) situations where bus factor should be considered. For example, an employee exiting a company for a new job, because a family member was sick, et al.
It’s generally considered better for the organization to have higher bus factors on projects, but it’s also beneficial to those working on the project. If you become the go-to person on a project and it can’t succeed without you, you’ll be on the hook for that project as long as you work at the company. You’ll have a much harder time transitioning to new projects and growth opportunities. If you leave, you may also be dooming the project, which besides not being a great feeling, may leave you with little to point to as an accomplishment in the future.
This post offers motivation and strategies for making your projects more maintainable.
Maintainability as a product
So much of our effort in software and product development is centered around the functionality for the end user. Does it fulfill the user stories? Does it meet requirements? If so, we often ship and consider the job done until the next round of user stories and requirements.
But there is another set of people using the product: its maintainers. This group might include the original creators and it may include others who come on later, but they are nonetheless impacted by the product and deserve the same level of empathy as anyone else. So let’s try writing some user stories for them. We’ll use the common phrasing, “As a <persona>, I want to <action> so that <reason>.” As you’re developing the product, evaluate the current state against the user stories you’ve written for it. See if you have all the artifacts necessary to execute the user stories successfully.
- As a new junior developer on the team, I want to find where some
inefficient queries are being made so that I can optimize a page.
- Let’s assume we have a traditional Rails application where the view is rendered by the server and it uses ActiveRecord models in the usual manner. If the junior developer searches for Rails documentation and finds the conventions it uses, he or she might be able to go directly from a slow query log to the code in the model or controller that formed the complicated query and edit it. In this case, simply using well-documented, industry-standard conventions was sufficient to resolve the story.
- As a seasoned developer who has been on the project for a while, I
want to understand our product’s current plugin architecture so I can
resolve an issue with load ordering that confuses some users.
- In this story, say we have developed a custom plugin architecture for our product. Hopefully, there is documentation for the user which explains the interface. The output of the “resolution” of this issue may be more user documentation or code changes to make a more natural load ordering. In order for the developer to begin solving the problem, is there documentation or a comment that explains the background architecture? Can this developer be expected to know where to find it? Does it describe the load ordering? Whatever the cost to get to this understanding is the technical debt to resolve this issue.
- As a product manager, I want to understand the technical reasons
for a privacy issue discovered in a bug bounty program so that I can
explain the problem to users.
- Does your product have documentation on how it deals with sensitive personally identifiable information (PII)? If not, then resolving this issue will require a developer to dig into the code and figure out the issue. This cost may be acceptable to you and your organization, but then you have another maintenance user story for the developer. Does that developer then have everything he or she needs to find out the issue quickly?
Notice in the user stories above (as with most user stories), the personas are key. The requirements for a product manager to resolve an issue are very different from those that a developer faces. But both parties (and others) are involved in the long-term ownership of the product and deserve attention.
The stories that I’ve presented here are somewhat specific and you might imagine that coming up with such stories before creating a project is difficult. That’s absolutely true, but it doesn’t mean you can’t or shouldn’t do it. All of these problems can be imagined by those with experience and empathy for the future maintainers. (I define empathy as caring about the situation of someone because you have had a similar experience.) You can practice creating such user stories by looking at the maintainability of your current products and writing stories for problems you’ve had to solve since their release.
Depending on the user story, you may also be able to use one of the three interaction types I describe in a previous post, Empathy, Sympathy, and Compassion in Product Development, namely customer interviews, customer observation, and doing what the customer does. In this case, replace the word “customer” with whichever persona pertains to your user story. It might be a new developer to the project (an opportunity you may not have often, so take advantage of the person’s unfamiliarity during his or her on-boarding) or the product manager currently working on the product. Even with these interaction types, you may have to rely more on sympathy (concern for someone not based on experience) than empathy for user story development.
Note that the user story formula I used contains an action. If you are writing user stories and evaluating against solving them, you are preparing your product or project for actionable maintenance. In other words, we’re not optimizing for just “getting to know a project” and nor should we. There’s not much business value in knowing a project’s structure without an associated action. Maintainers who are not performing an action will likely not have as concretized knowledge as when performing an action. Moreover, they aren’t actually “maintaining” anything when becoming familiar with a product without a goal.
Getting back to the concept of bus factor, remember that employee departures can happen at any time or priorities can get shifted to a different project temporarily, leaving a project in limbo until the team can return to it. Thus the bus factor is always relevant. By making maintainability part of the deliverables of each sub-part of the product, we retain the possibility that we or someone else can pick up right where we left off, with a well-understood (but hopefully minimal) level of on-boarding overhead.
The concept of continuous integration (CI) has been around for a while and generally exists to validate the quality of the software being produced with each check in. We could derive an analogous concept of continuous maintainability, but at this point, no automated processes exist to validate the maintainability of a project. We can nibble around the edges of the code with style checkers that look for javadocs and the like, but this approach hardly gets us all the way to the level of automation as exists in continuous integration.
We must, unfortunately, rely on more discipline and the motivation that we are producing something that we can hand off if we want to work on something else. Nonetheless, there is precedent for similar processes; we might have a better analogy to code reviews than to CI to enforce maintainability. In code reviews, by requiring that at least one other developer reviews code before it’s checked in, we can catch mistakes and evaluate the comprehensibility of the code. There’s certainly a benefit to maintainability here as well. However, we need to go further to ensure specific maintainability features.
Staying within the framework of code reviews, try assigning a developer with no context on your commit to review your code and give him or her no direct primer on the project. Are they able to jump in and see what issue your code is addressing? Do they come up with the same broader architectural concerns as developers familiar with the project? The ease with which he or she is able to understand your commit is likely proportional to the maintainability of your project.
Note that a large commit will likely be less comprehensible to this developer and that it will take him or her a long time to get up to speed to understand it fully. This difficulty may happen when you ask him or her to do this code review, but think of what will happen in the future when someone maintaining the project comes upon this commit. In addition to facing the size of this commit, he or she may not have you around to explain it. Even if you are around, you may well have lost the context yourself. In other words, keep your commits small, focused, and well described to support maintainability.
Remember that non-developers are required to maintain your product as well. For product managers, it may be their role to review documentation (especially internal) before each release to validate they understand the product sufficiently. QA may also be a valuable source of information as they discover issues with the product.
Maintainability via empathy and sympathy
In this post, I’ve suggested that we treat the maintainability of a product as a product in and of itself. Use your experience (or at least your imagination) to empathize or sympathize with those who will maintain your product after you’ve departed it, either for something in the same company or not. Your goal should be to get those maintainers up and running quickly and independently, just as you would have liked when working on someone else’s product.