The Art of Agile Development: Collective Code Ownership
May 20, 2010
The second edition is now available! The Art of Agile Development has been completely revised and updated with all new material. Visit the Second Edition page for more information, or buy it on Amazon.
- Next: Documentation
- Previous: Continuous Integration
- Up: Chapter 7: Releasing
in 99 words
With collective code ownership, everyone shares responsibility for code quality. Anyone can make necessary changes anywhere, and everyone is expected to fix problems they find. To make it work, let go of your ego. Take as much pride in the team's code as in your own code.
When working with unfamiliar code, ask the local expert to pair with you. If he's unavailable, infer high-level class responsibilities and method behaviors from their names, and rely on unit tests for further documentation and as your safety net. As you work, help the next person by taking opportunities to refactor.
The following text is excerpted from The Art of Agile Development by James Shore and Shane Warden, published by O'Reilly. Copyright © 2008 the authors. All rights reserved.
Collective Code Ownership
We are all responsible for high quality code.
There's a metric for the risk imposed by concentrating knowledge in just a few people's heads—it's called the truck number. How many people can get hit by a truck before the project suffers irreparable harm?
It's a grim thought, but it addresses a real risk. What happens when a critical person goes on holiday, stays home with a sick child, takes a new job, or suddenly retires? How much time will you spend training a replacement?
Collective code ownership spreads responsibility for maintaining the code to all the programmers. Collective code ownership is exactly what it sounds like: everyone shares reponsibility for the quality of the code. No single person claims ownership over any part of the system, and anyone can make any necessary changes anywhere.
Fix problems no matter where you find them.
In fact, improved code quality may be the most important part of collective code ownership. Collective ownership allows—no, expects—everyone to fix problems they find. If you encounter duplication, unclear names, or even poorly designed code, it doesn't matter who wrote it. It's your code. Fix it!
Making Collective Ownership Work
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 edits your code, enjoy how the code improves when you're not working on it. Rather than pushing your personal design vision, discuss design possibilities with the other programmers and agree on a shared solution.
Always leave the code a little better than you found it.
Collective ownership requires a joint commitment from team members to produce good code. When you see a problem, fix it. When writing new code, don't do a half-hearted job and assume somebody else will fix your mistakes. Write the best code you can.
On the other hand, collective ownership means that you don't have to be perfect. If you've produced code that works, is of reasonable quality, 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 it needs it.
Working with Unfamiliar Code
If you're working on a project that has knowledge silos—in other words, little 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?
To begin, take advantage of pair programming. When somebody picks a task involving code you don't understand, volunteer to pair with him. When you work on a task, ask the local expert to pair with you. Similarly, if you need to work on some unfamiliar code, take advantage of your shared workspace to ask a question or two.
Rely on your inference skills as well. You don't need to know exactly what's happening in every line of code. In a well-designed system, all you need to know is what each package (or namespace) is responsible for. Then you can infer high-level class responsibilities and method behaviors from their names. (See Refactoring in Chapter 9.)
Inferring high-level design from a brief review of the code is a black-belt design skill that's well worth learning. Take advantage of every opportunity to practice. Check your inferences by asking an expert to summarize class responsibilities and relationships.
Rely on the unit tests for further documentation and as your safety net. 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 work, look for opportunities to refactor the code. In particular, I often find that refactoring code helps me to understand it. It benefits the next person too; well-factored code tends toward simplicity, clarity, and appropriate levels of abstraction.
If you're just getting started with XP, you might not yet have a great set of unit tests and the design might be a little flaky. In this case, you may not be able to infer the design, rely on unit tests, or refactor, so pairing with somebody who knows the code well becomes more important. Be sure to spend extra time introducing unit tests and refactoring so that the next person can take ownership of the code without extra help.
"Of course nobody can understand it... it's job security!"
—Old programmer joke
It's not easy to let a great piece of code out of your hands. It's difficult sometimes to subsume the desire to take credit for a particularly clever or elegant solution, but it's necessary for your team to take advantage of all of the benefits of collaboration.
It's also 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 skills. Even if you're an absolute database guru, you don't have to write only database code through out the project. If writing a litte UI code sounds interesting, find a programming partner and have at it.
You also don't have to carry the maintenance burden for a piece of code someone assigned you to write. Generally, the pair that finds a bug fixes the bug. They don't need your permission. Even better, they don't necessarily need your help; they may know the code now as well as you did when you wrote it.
It's a little scary at first to come into work and not know exactly what 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.
We have a really good UI designer/database programmer/scalability guru. Why not take advantage of those skills and specialties?
Please do! Collective code ownership shares knowledge and improves skills, but it won't make everyone an expert at everything.
Don't let specialization prevent you from learning other things, though. If your specialty is databases and the team is working on user interfaces this week, take on a user interface task. It can only improve your skills.
How can everyone learn the entire codebase?
People naturally gravitate to one part of the system or another. They become experts in particular areas. Everybody gains a general understanding of the overall codebase, but each person only knows the details of what he's worked with recently.
The tests and simple design allow this approach to work. Simple design and its focus on code clarity make it easier to understand unfamiliar code. The tests act both as a safety net and as documentation.
Doesn't collective ownership increase the possibility of merge conflicts?
It does, and so it also requires continuous integration. Continuous integration decreases the chances of merge conflicts.
In the first week or two of the project, when there isn't much code, conflicts are more likely. Treat the code gently for the first couple of iterations. Talk together frequently and discuss your plans. As you progress, the codebase will grow, so there will be more room to make changes without conflict.
We have some pretty junior programmers, and I don't trust them with my code. What should we do?
Rather than turning your junior programmers loose on the code, make sure they pair with experienced members of the team. Keep an eye on their work and talk through design decisions and trade-offs. How else will they learn your business domain, learn your codebase, or mature as developers?
Different programmers on our team are responsible for different projects. Should the team collectively own all of these projects?
If you have combined programmers working on several projects into a single team (as described in the discussion of team size in Is XP Right For Us? in Chapter 4), then yes, the whole team should take responsibility for all code. If your programmers have formed multiple separate teams, then they usually should not share ownership across teams.
When you practice collective code ownership, you constantly make minor improvements to all parts of the codebase, and you find that the code you've written improves without your help. When a team member leaves or takes a vacation, the rest of the team continues to be productive.
Don't use collective code ownership as an excuse for no code ownership. Managers have a saying: "shared responsibility is no responsibility at all." Don't let that happen to your code. Collective code ownership doesn't mean someone else is responsible for the code; it means you are responsible for the code—all of it. (Fortunately, the rest of the team is there to help you.)
Collective code ownership requires good communication. Without it, the team cannot maintain a shared vision, and code quality will suffer. Several XP practices help provide this communication: a team that includes experienced designers, sitting together, and pair programming.
Although they are not strictly necessary, good design and tests make collective code ownership is easier. Proceed with caution unless you use test-driven development, simple design, and agree on coding standards. To take advantage of collective ownership's ability to improve code quality, the team must practice relentless refactoring.
To coordinate changes, you must use continuous integration and a concurrent model of version control.
A typical alternative to collective code ownership is strong code ownership, in which each module has a specific owner and only that person may make changes. A variant is weak code ownership, in which one person owns a module but others can make changes so long as they coordinate with the owner. Neither approach, however, shares knowledge or enables refactoring as well as collective ownership does.
- Pair Programming
If you cannot use collective code ownership, you need to adopt other techniques to spread knowledge and encourage refactoring. Pair programming may be your best choice. Consider holding weekly design workshops as well to review the overall design and brainstorm improvements.
I recommend against strong code ownership. It encourages rigid silos of knowledge, making you vulnerable to any team member's absence. Weak code ownership is a better choice, although it still doesn't provide the benefits of collective ownership.
- Next: Documentation
- Previous: Continuous Integration
- Up: Chapter 7: Releasing