Sunday May 17, 2009
The Culture of Good Software
Creating a team that insists on excellence
By Colin Lieberman
Ever notice how some teams or projects or companies you’ve worked with produce strong code, while others are a mess? Some teams’ work product is relatively free of major errors, is easy to read and get up to speed on, and is well documented. Other teams’ or projects’ code most closely resembles your drawer of extra usb and ethernet cables.
I used to think that this difference was attributable to personal qualities of the developers -- that some engineers were more thorough, or more forward thinking, or just better. I don’t think that way anymore.
I think the phenomenon of well commented, easy to use code, as opposed to commentless, documentation-free spaghetti, is sociological. Some teams have a culture of excellence, and others don’t. The social and cultural pressures to produce well commented, well thought-out code with documentation are the same as the social and cultural pressures around littering.
A study published late last year showed that people are more inclined to litter and ignore signage in areas blighted with graffiti and existing trash. This research confirms what most of us know intuitively, and explains the success of no broken windows policies.
The same social forces are at work in software development. If your team insists on keeping code clean, performant, and well-documented, team members, as humans, will naturally strive to meet the expectations of the group.
Here’s how to make it happen.
When fostering a culture of excellence, there is no better place to begin than the Joel Test. If you don’t know the Joel Test, go read that article now.
The value of these 12 points can not be understated. They really help focus engineering team members on the needs of the group to work together, and help suppress the urge for cowboy programming: long, solitary sessions, which while romantic, are destructive to a team’s ability to work together.
The Joel Tests helps focus your efforts beyond the coding task in front of you, and on to the broader need of the team to ship a product that works. You can really cement this team focus with occasional non-work-related events, like a dinner or trip to the movies, with all members of the team, including QA. When people have spent time making small talk over drinks, they are much less likely to think of other engineers, or QA testers, as faceless nobodies on whom they can dump lousy code.
Once you’ve got the basics working, the next step toward excellence is to make sure that engineers don’t work in silos. When one feature set is exclusively Bob’s world, and another part of the application is Lucy’s property, neither Bob nor Lucy can go on vacation or find a new job without friction.
Cross-training team members on all parts of the application means your team is much less brittle around sick and vacation time. Engineers, despite the stereotypes, have lives and families, and should be able to take time away from work without the company or the product suffering.
Furthermore, having multiple engineers at work on the same features means that problematic assumptions, errors, or sloppily written methods are much more likely to be caught in development than in QA, or heaven-forbid, production.
Rituals and Ceremonies
An important adjunct to cross-training everybody across the application, are regular, say weekly or biweekly, code review sessions. This is where the whole engineering team comes together for half an hour or an hour to go over one major feature or class in the application, typically something one team member has been working on and wants to critique before signing off.
The benefits of regular code reviews are tremendous:
- increased understanding of the whole application by all team members
- amazing opportunity to catch coding errors, security issues, and bad assumptions
- culturally, a chance to remind the whole team of standards around variable names and brace usage
- a socially acceptable context for important criticism like “this needs more comments” and “I don’t understand what this method does”
- a forum for the more experienced engineers to apply their knowledge of architecture and performance to all areas of the application, while teaching these skills to less experienced developers
When you ritualize regular code reviews, you create the trappings of a culture that has shared values that are regularly communicated to members. These touchstones in the development process become a vehicle for the culture of excellence you want to create.
Don’t overdo it though - good engineers are cynical and cagey, and don’t like being pandered to. Some teams will burn out on regular reviews if they’re more frequent than once a month, others will do well with weekly reviews.
Writing it Down
There are many different kinds of documentation. For day-to-day engineering, what’s frequently lacking is the kind of documentation that explains the big-picture purpose of a feature, and the relationships among the parts of the code that go into it.
This is the kind of documentation that’s useful to engineers trying to get up to speed on a code base, or when going back to fix a bug a year later.
It rarely gets written because by the time the code for a feature is in place, everybody’s ready to move on to the next feature. The trick is to stop thinking of documentation as (a) separate tasks, and (b) as something done after the fact.
Encourage your team to think of documentation like this instead:
- Engineering notes that are started before undertaking a new feature, and kept up-to-date through its development
- An integral part of the task requirements
When working, have the documentation wiki open in another browser tab. Put links to the documentation in code comments. Require that time to document features is included in task estimates, and that tasks are considered incomplete if the code is poorly documented.
The test of the quality of your documentation is how long it takes a new developer to start working productively.
Making it Work
I’ve discussed a number of techniques:
- The Joel Test for effective software development, and the focus on group, rather than individual goals
- Cross-training engineers on overlapping parts of the code base
- Regular code reviews as an opportunity to improve code, and as a vehicle for the culture of excellence and professionalism
- Maintaining working documentation on big-picture issues intended for use by other engineers
When you’ve got these practices in place, your teammates will feel good about themselves and the work they’re doing, but getting there can be a challenge. I’ve heard objections to regular, automated builds that it would be “too burdensome” on engineers to insist that their code works before checking it in. I’ve heard objections to maintaining proper documentation that there just isn’t enough time to get all the coding done and write docs.
There are logical responses you can use to try to disprove these beliefs, but don’t waste your breath. Some people are just resistant to change, and their egos seem too fragile for the kind of confidence required to work in an open, discursive environment. If these attitudes are coming from management, and there’s no way to go over their heads, either try to convince them to give you six months to humor you on this, or find another job. If these attitudes are coming from team members, then just get the folks above you to back these changes as important parts of a professional work environment.
Nobody worth working with will want to go back to the old way of doing things after working for a year in a positive, team-focused environment that expects and demands high quality work from all its members.