The Art of Agile Development: Coding Standards
September 2, 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: Iteration Demo
- Previous: Stand-Up Meetings
- Up: Chapter 6: Collaborating
in 99 words
In team software development, we create a collective work that is greater than any individual could create on his own. Arguing about style gets in the way.
When creating a coding standard, your most important achievement will be learning how to disagree constructively. To succeed, create the minimal set of standards you can live with. Focus on consistency and consensus over perfection. Remember that few decisions are irrevocable in agile development.
Assume your colleagues are professional and well-meaning. If they deviate from the standard, discuss reasons rather than placing blame. No coding standard can substitute for professional judgement.
Fists fly, dust billows--
Tomatoes die, peas cry, as
we choose rose's hue.
RantGet a Life!
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.
We embrace a joint aesthetic.
Back in the days of the telegraph, as the story goes, telegraph operators could recognize each other on the basis of how they keyed their dots and dashes. Each operator had a unique style, or fist, that experts could recognize easily. Programmers have style, too. We each have our own way of producing code. We refine our style over years until we think it's the most readable, the most compact, or the most informative it can be.
Individual style is great when you're working alone. In team software development, however, the goal is to create a collective work that is greater than any individual could create on his own. Arguing about whose style is best gets in the way; it's easier if we work together in a single style.
XP suggests creating a coding standard: guidelines to which all developers agree to adhere when programming.
I once led a team of four programmers who had widely differing approaches to formatting. When we discussed coding standards, I catalogued three different approaches to braces and tabs. Each approach had its own vigorous defender. I didn't want us to get bogged down in arguments, so I said that people could use whatever brace style they wanted.
The result was predictable: we had three different approaches to formatting in our code. I even saw two different ways of indenting within a single, short method.
You know what surprised me? It wasn't that bad. Sure, the layout was ugly, and I would have preferred consistency, but the code was still readable. In the end, the rest of our coding standard mattered much more than formatting.
We all agreed that clearly named variables and short methods were important. We agreed to use assertions to make our code fail fast, not to optimize without measurements, and never to pass null references between objects. We agreed on how we should and shouldn't handle exceptions, what to do about debugging code, and when and where to log events. These standards helped us far more than a consistent formatting style would have because each one had a concrete benefit. Perhaps that's why we were able to agree on them when we couldn't agree on formatting styles.
Don't get me wrong: a consistent formatting standard is good. If you can agree on one, do! However, when you're putting together your coding standard, don't fall into the trap of arguing about formatting. There are more important issues.
How to Create a Coding Standard
The most important thing you will learn is how to disagree.
Creating a coding standard is an exercise in building consensus. It may be one of the first things that programmers do as a team. Over time, you'll amend and improve the standards. The most important thing you may learn from creating the coding standard is how to disagree constructively.
To that end, I recommend applying two guidelines:
Create the minimal set of standards you can live with.
Focus on consistency and consensus over perfection.
Hold your first discussion of coding standards during the first iteration. The project will typically start out with some discussion of stories and vision, then some release planning and iteration planning (see Go! in Chapter 4). After iteration planning, customers and testers will continue working on the release plan. That's a great time for programmers to talk about coding standards.
The best way to start your coding standard is often to select a industry-standard style guide for your language. This will take care of formatting questions and allow you to focus on design-related questions. If you're not sure what it should encompass, starting points include:
Development practices (start with the practices in Chapter 9 and Chapter 7)
Tools, keybindings, and IDE
File and directory layout
Error handling and assertions
Approach to events and logging
Design conventions (such as how to deal with null references)
Focus on agreements.
Limit your initial discussion to just one hour. Write down what you agree on. If you disagree about something, move on. You can come back to it later.
I like to write each item that we agree upon on a flip chart so we can tape it to a wall in our open workspace. If you can find a neutral observer to take notes (such as your project manager), so much the better.
If you have trouble, take a step back and talk about your goals for the software and the results you would like to see. Agree about these issues first, even if you disagree about specific approaches. You will have many opportunities to improve your standard. Make the most important decisions now, and move on.
Depending on your team, this may be a contentious discussion. In that case, consider bringing in a professional facilitator to redirect the discussion to your team goals when things gets heated. Your HR department might be able to provide someone, or you can use an outside consultant.
Plan to hold another one-hour coding standard meeting a few days later, and another one a few weeks after that. The long break will allow you to learn to work together and to try out your ideas in practice. If there's still disagreement, experiment with one approach or the other, then revisit the issue.
Hold these initial meetings as often as they're useful. After that, change the standard at any time. Just stand up, announce your intention to the team, and, if everybody agrees, change the flip chart. Retrospectives are another good time to discuss changes to the coding standard.
The thumb vote is a quick way to check for consensus. Someone asks a question and everyone holds their thumb up (meaning "I agree"), sideways ("I'll go along with the group"), or down ("I disagree and want to explain why").
Over time, some of the items in the standard will become second nature. Cross them off to make room for more important issues. As you work together, you will recognize ways in which new standards can help. Add these new standards to the list in the same way as before, as long as everybody agrees to try them.
No matter what standards you choose, someone will be probably unhappy with some guideline even with a consensus-based approach. You'll probably find some practices jarring and grating at first. Over time, you'll get used to it. Coding standards are, in many ways, an aesthetic choice: it doesn't really matter what the standard is, as long as it's consistent and thoughtful. One of the marks of a professional is the willingness to put aside personal aesthetics for a team aesthetic.
Dealing with Disagreement
It's possible to pressure a dissenter into accepting a coding standard she doesn't agree with, but it's probably not a good idea. Doing so is a good way to create resentment and discord.
Instead, remember that few decisions are irrevocable in agile development; mistakes are opportunities to learn and improve. Ward Cunningham put it well:1
It was a turning point in my programming career when I realized that I didn't have to win every argument. I'd be talking about code with someone, and I'd say, "I think the best way to do it is A." And they'd say, "I think the best way to do it is B. I'd say, "Well no, it's really A." And they'd say, "Well, we want to do B." It was a turning point for me when I could say, "Fine. Do B. It's not going to hurt us that much if I'm wrong. It's not going to hurt us that much if I'm right and you do B, because, we can correct mistakes. So [let's] find out if it's a mistake."
Go ahead and leave the contested item out of the standard. Maybe lack of standardization in that area will lead to a mess. If it does, the team will learn from the experience and you can change the standard.
Adhering to the Standard
People make mistakes. Pair programming helps developers catch mistakes and maintain self-discipline. It provides a way to discuss formatting and coding questions not addressed by the guidelines. It's also an excellent way to improve the standard; it's much easier to suggest an improvement when you can talk it over with someone first.
Collective code ownership also helps people adhere to the standard, because many different people will edit the same piece of code. Code tends to settle on the standard as a result.
There are less effective approaches. Some teams use automated tools to check their source code for adherence to the coding standard. Others program their version control system to reformat files upon check-in. I don't like either approach: to me, the latter says that you don't trust people to make good decisions on their own, and the former tends to raise false warnings.
Assume your colleagues are professional and well-meaning.
I've also heard of teams who elevate their coding standards to requirements and punish infractions. The idea of enforcing a coding standard leaves a bad taste in my mouth. Your teammates are presumably professionals who pride themselves on doing good work. No coding standard can substitute for professional judgment. Try not to get too upset when you see people deviating from the standard.
Assume your colleagues are professional and well-meaning. If someone is not following the standard, assume that there's a good reason—even if all the evidence is to the contrary. Your challenge is to find that reason and address it. This approach shows respect for others and this will improve others' respect for you.
Before you do anything, ask yourself whether the coding standard was really a team effort. If everybody agreed to every item, they should have no problem following the standard.
Start by talking with your colleague alone to see if there's a disagreement. Take an attitude of collaborative problem solving: instead of saying "Why aren't you propagating exceptions like we agreed?" ask, "What do you think about the 'propagate exceptions' standard we agreed on? Should we keep it?" Give objections full consideration, raise them with the rest of the team, and consider changing the standard.
If the objector agrees with the standard but isn't applying it, it's possible that the standard isn't appropriate in every situation. Ask about specific cases you've noticed. Again, be collaborative, not confrontational. Say something like, "I think we're on the same page regarding the importance of propagating exceptions. In that case, can you explain what's happening in this method? I don't understand why this code doesn't propagate the exception here."
During this discussion, you may learn that the objector doesn't understand the standard. By this time, you should be in a good situation to discuss the standard and what it means. If he's a junior programmer and needs more help, coordinate with the rest of the team to make sure he gets plenty of pairing time with experienced developers.
There is another possibility for teams new to XP. Switching to XP is a big change and can make people feel like they've lost control. Sometimes they react by picking small things that they refuse to change. An obstinate desire to stick with a particular coding standard, regardless of the wishes of the rest of the team, might be a symptom of this reaction.
In this case, your best solution may be to let the infractions slide for several months. Over time, as team members become more comfortable with the changes in their environment, they'll relax and be more willing to compromise.
We have legacy code that doesn't fit our standard. Should we fix it?
Leave old code alone if it works and you don't need to read or touch it otherwise. It's expensive and risky to spend a lot of time fixing legacy code upfront. Instead, as you modify and refactor those sections of code, bring them up to the new coding standards. When you fix a bug, add a feature, or improve abstraction and factoring, use the new standards on everything you modify.
You can also use an automated tool to perform large-scale formatting changes. Don't spend too much time on this, but if you can do it easily, you might as well. I prefer to integrate immediately before and after such an operation, because reformatting changes tend to disguise other changes. Be aware that making such large-scale changes can render your version control system's change history much more difficult to read.
When you agree on coding standards and conventions, you improve the maintainability and readability of your code. You can take up different tasks in different subsystems with greater ease. Pair programming moves much more smoothly, and you look for ways to improve the expressability and robustness of your code as you write it.
Don't allow coding standards to become a divisive issue for your team.
Some teams work so well together they don't need an written coding standard; their coding standard is implicit.
If you have a new team, create a written coding standard even if everybody gets along well. New teams often go through an initial honeymoon period in which team members are reluctant to disagree with each other. Eventually, disagreements will come out. It's much better to create a standard before problems escalate.
- Next: Iteration Demo
- Previous: Stand-Up Meetings
- Up: Chapter 6: Collaborating