AoAD2 Practice: Collective Code Ownership

This is an excerpt from The Art of Agile Development, Second Edition. Visit the Second Edition home page for additional excerpts and more!

This excerpt is copyright 2007, 2021 by James Shore and Shane Warden. Although you are welcome to share this link, do not distribute or republish the content without James Shore’s express written permission.

Collective Code Ownership

Audience
Developers

We are all responsible for all our code.

Agile teams collectively own their work, as described in the “Key Idea: Collective Ownership” sidebar. But how does that apply to code?

Collective code ownership means the team shares responsibility for its code. Rather than assigning modules, classes, or stories to specific individuals, the team owns it all. It’s the right and responsibility to make improvements to any aspect of your team’s code at any time.

Fix problems no matter where you find them.

In fact, improved code quality is one of the hidden benefits of collective code ownership. Collective ownership allows—no, expects—everyone to fix the problems they find. If you encounter duplication, unclear names, poor automation, or even poorly designed code, it doesn’t matter who wrote it. It’s your code. Fix it!

Making Collective Ownership Work

Allies
Mob Programming
Task Planning

Collective code ownership requires careful coordination around design and planning. If you’re using mob programming, that coordination comes for free. Otherwise, your task planning meeting is a good time to start the discussion. When you discuss how to break down tasks, talk about your design. Write tasks in terms of how your design will change: “Add endpoint to UserReportController.” “Update ContactRecord.” “Add columns to GdprConsent database table.”

When you’re ready for a new task, you can pick up any task from the planning board. In many cases, you’ll just take the next one off the list, but it’s okay to jump ahead a bit to choose a task that you’re interested in or particularly well-suited for.

Ally
Done Done

In an ideal world, your team will swarm each story: everyone will choose tasks for the same story and focus on getting the story “done done” before moving on to the next. This minimizes work in progress (see the “Key Idea: Minimize Work in Progress” sidebar) and exposes risks early.

Don’t jump ahead to another story just because you don’t know how to coordinate.

In practice, it’s okay for people to jump ahead to the next story when the current one is close to completion. Just be careful: when you’re new to collective ownership, it’s going to be easy to accidentally end up with everyone taking de facto ownership of separate stories rather than truly working together. Don’t jump ahead to another story just because you don’t know how to coordinate.

When you pick up a task that’s closely related to another person or pair’s, have a quick discussion with them. Perhaps they’ve grabbed a frontend task and you’ve grabbed the corresponding backend task. Take a moment to get on the same page about the API. One or both of you can stub in the API with do-nothing code, then one of you can be responsible for filling it in. Whoever commits their code second is responsible for double-checking that it works together.

Ally
Pair Programming

As you work on the code, you’ll come up with ideas that affect other people’s work. Pairing will help them spread around the team. You can also use the daily stand-up to summarize new ideas. If you’re not using pairing or mobbing, you might need to add a daily design review.

Some ideas warrant immediate discussion. In a physical team room, just stand up and announce what you want to talk about. People will come join you. In a remote team room, announce the topic in your group chat, and invite people to join you in a videoconference. The “Drop in and Drop Out” section has more details.

Egoless Programming

Collective code ownership requires letting go of a little bit of ego. Rather than taking pride in your code, take pride in your team’s code. Rather than complaining when someone modifies code you wrote, enjoy how the code improves when you’re not working on it. Rather than pushing your personal design vision, discuss design possibilities with your teammates and agree on a shared solution.

Collective ownership also requires a joint commitment from team members to produce good code. When you see a problem, fix it. When writing new code, don’t assume somebody else will fix your mistakes. Write the best code you can.

On the other hand, collective ownership also means you don’t have to be perfect. If your code works and you’re not sure how to make it better, don’t hesitate to let it go. Someone else will improve it later, if and when the code needs it.

Always leave the code a little better than you found it.

Conversely, when you’re working in “someone else’s” code (but it’s not someone else’s—it’s yours!), avoid the temptation to make personal judgments about them based on their code. But do always leave the code a little better than you found it. If you see an opportunity for improvement, don’t be shy. You don’t need to ask permission. Do it!

Collaborating Without Conflict

At first, collective code ownership is an opportunity for conflict. All the little annoyances about your colleagues’ work styles are double-underlined with a bright purple highlighter. This is a good thing—really!—because it gives you a chance to align your style. But it can be frustrating at first.

Allies
Alignment
Mob Programming
Retrospectives
Team Dynamics

To help the process go more smoothly, decide on important coding, design, and architectural standards as part of your alignment chartering session. When you first adopt collective code ownership, try mob programming for a week or two so you can hash out important differences. Bring up areas of disagreement in your retrospectives and come up with plans for resolving them. Pay attention to team dynamics.

Allies
Stand-Up Meetings
Task Planning
Pair Programming
Continuous Integration

If you don’t use mob programming, you’ll need a way to avoid stepping on each other's toes during day-to-day work. Daily stand-up meetings are a good way to coordinate, as long as they’re kept brief and focused. The task planning board will help maintain your situational awareness, especially if it’s visible from where you sit.

Pair programming will help you keep up with everyone’s changes. Your partner will often be aware of changes you aren’t, and vice versa. When they aren’t, pair programming makes it easier to ask another pair for help. People who are pairing can take brief interruptions without disturbing their progress—one person just keeps going while their partner deals with the interruption.

In fact, make a point of encouraging people to ask for help when they’re stuck. There’s no point in somebody banging their head against a wall for 30 minutes if somebody else on the team already knows the answer.

Finally, continuous integration will prevent painful merge conflicts and keep everyone’s code in sync.

Working with Unfamiliar Code

If you’re working on a project that has knowledge silos—pockets of code that only one or two people understand—then collective code ownership might seem daunting. How can you take ownership of code that you don’t understand?

Mob programming may be your best choice, at least to start. It will help the whole team share their knowledge with one another quickly. If that’s not to your taste, pair programming also works.

To use pairing to expand your knowledge, volunteer to work on tasks that you don’t understand. Ask somebody who knows that part of the system to pair with you. While pairing, resist the temptation to sit back and watch. Instead, take the keyboard and ask them to guide you. Use your control of the keyboard to control the pace: ask questions and make sure you understand what you’re being asked to do. The “Teaching Through Pairing” section has more.

If nobody understands the code, exercise your inference skills. You don’t need to know exactly what’s happening in every line. In a well-designed system, all you need to know is what each package, namespace, or folder is responsible for. Then you can infer high-level class responsibilities and method behaviors from their names. The “Reverse-Engineering the Design” section goes into more detail.

Allies
Test-Driven Development
Refactoring

Well-written tests also act as documentation and a safety net. Skim the test names to get an idea of what the corresponding production code is responsible for. If you’re not sure how something works, change it anyway and see what the tests say. An effective test suite will tell you when your assumptions are wrong.

As you learn, refactor the code to reflect your improved understanding. Fix confusing names and extract variables and functions. This will codify your understanding and help the next person, too. Arlo Belshee’s “Naming as a Process” technique [Belshee2019] is a nice formalization of this approach.

If you’re working with poorly designed code that nobody understands and that doesn’t have any tests, all is not lost. You can use characterization tests to refactor safely. See the “Adding Tests to Existing Code” section for details.

Benefits to Programmers

Of course nobody can understand it...it’s job security!

Old programmer joke

Collective ownership makes a lot of sense for an organization. It reduces risk, improves cycle time, and improves quality by bringing more minds to bear on the code. But does it make sense for programmers? Won’t collective ownership make it more difficult for your contributions to be recognized?

Honestly...it could. As discussed in the “Change Harmful HR Policies” section, Agile requires that your organization recognize and value team contributions more than individual heroics. If that’s not true for your organization, collective code ownership might not be a good fit.

Even if your organization values teamwork, it’s not easy to let a great piece of code out of your hands. It can be difficult to subsume the desire to take credit for a particularly clever or elegant solution.

But it is good for you as a programmer. Why? The whole codebase is yours—not just to modify, but to support and improve. You get to expand your technical skills. You’ll learn new design and coding techniques from working with other team members. When teaching people about your area of expertise, you get to practice your mentoring skills, too.

You don’t have to carry the maintenance burden for every piece of code you write, either. The whole team has your back. Over time, they’ll know your code as well as you do, and you’ll be able to go on vacation without being called with questions or emergencies.

It’s a little scary, at first, to come into work and not know exactly which part of the system you’ll work on, but it’s also freeing. You no longer have long subprojects lingering overnight or over the weekend. You get variety and challenge and change. Try it—you’ll like it.

Questions

We have a really good frontend developer/database programmer/scalability guru. Why not take advantage of their skills?

Please do! Collective code ownership means everybody contributes to every part of the system, but you’ll still need experts to lead the way.

How can everyone learn the entire codebase?

People naturally gravitate to one part of the system or another. They become expert in particular areas. Everyone gains a general understanding of the overall codebase, but they don’t know every detail.

Allies
Simple Design
Test-Driven Development
Pair Programming
Mob Programming

Several practices enable this approach to work. Simple design and its focus on code clarity make it easier to understand unfamiliar code. Tests act as a safety net and documentation. Pairing and mobbing allow you to work with people who have the details you don’t.

Different programmers on our team are responsible for different products. Should the team collectively own all these products?

If you’ve combined programmers onto a single team, then yes, the whole team should take responsibility for all of their code. If you have multiple teams, then they may or may not share ownership across teams, depending on how you approach scaling. See the “Scaling Agility” chapter for details.

Prerequisites

Allies
Alignment
Safety
Team Room
Task Planning
Stand-Up Meetings
Mob Programming
Pair Programming
Continuous Integration
Simple Design
Test-Driven Development

Collective code ownership is socially difficult. Some organizations have trouble letting go of individual rewards and accountability. Some programmers have trouble letting go of taking individual credit, or refuse to use certain programming languages. For these reasons, it’s important to talk with managers and team members about collective code ownership before trying it. These concerns should be part of your initial discussions about whether or not to try Agile (see the “Invest in Change” chapter) and brought up again during your alignment session.

Safety is critical. If team members don’t feel safe expressing and receiving criticism, or if they fear being attacked when they raise ideas or concerns, they won’t be able to share ownership of code. Instead, little fiefdoms will pop up. “Don’t change that code yet. You should talk to Antony first to make sure he’s okay with it.”

Collective ownership also requires good communication. You’ll need a team room, either physical or virtual, where people communicate fluidly. Use task planning and your task board to help people understand the work and stand-up meetings to coordinate it.

You need a way to ensure knowledge about changes spread throughout the team. Because anybody can make any change at any time, it’s easy to feel lost. Mob programming or pair programming are the easiest ways to do this. If those aren’t an option, you’ll need to put extra effort into communicating about changes. Code reviews aren’t likely to be enough. Most people instinctively migrate to documentation as a solution, but it’s costly, as the “Key Idea: Face-to-Face Conversation” sidebar discusses. Try lighter-weight solutions first. One option is to hold a 30-minute “design recap” every day to discuss new ideas and recent changes.

Because collective code ownership increases the likelihood that people will touch the same code, you need to minimize the likelihood of painful merge conflicts. Continuous integration is the best option. For new codebases, merge conflicts are more likely because there’s so little code. Mob programming can be a good way to bootstrap the codebase even if it’s not something you plan to use long-term.

Although they’re not strictly necessary, simple design and test-driven development are a good idea for teams using collective code ownership. They make the code easier to understand and change.

Despite this long list of prerequisites, collective code ownership is easy to practice once the necessary conditions are in place. All you need is a shared team agreement that everyone can and should work in any part of the code, seeking out and providing assistance as needed. You don’t need everybody to know every part of the code; team members just need to be able to ask for help when working in an unfamiliar part of the code, and to be generous in providing help in return.

Indicators

When your team practices collective code ownership well:

  • Everyone on the team constantly makes minor improvements to all parts of the code.

  • Nobody complains about team members changing code without asking permission first.

  • When you come back to code you originally wrote, you find that it improved without your involvement.

  • When a team member leaves or takes a vacation, the rest of the team handles their work without interruption.

Alternatives and Experiments

The main alternatives to collective code ownership are weak code ownership and strong code ownership. In weak code ownership, people can change any part of the code, but particular developers are responsible for ensuring their quality, and it’s polite to coordinate changes with them. In strong code ownership, all changes must go through the owner.

Both of these approaches detract from Agile’s emphasis on teamwork, although weak code ownership isn’t as bad as strong code ownership. It can be useful for teams that don’t use pairing or mobbing, or who have trouble leaving code better than they found it.

But try to use collective code ownership, if you can. Collective ownership is one of those Agile ideas that’s often overlooked, but is actually essential. It doesn’t always mean collective code ownership, but I think it’s an important part of the equation. Although it may be possible to have a fluent Delivering team without collective code ownership, I have yet to see it. Stick with this practice until you have a lot of experience as a fluent Delivering team.

Share your thoughts about this excerpt on the AoAD2 mailing list or Discord server. For videos and interviews regarding the book, see the book club archive.

For more excerpts from the book, see the Second Edition home page.

If you liked this entry, check out my best writing and presentations, and consider subscribing to updates by email or RSS.