(With apologies to Robert Fulghum)
I’m now coming up on 14 years of working with agile software development teams—either as a developer, architect, project manager, coach, or supervising executive. The more teams I work with, the more the problems seem to boil themselves down to a few root causes. And I find myself repeatedly reaching back to my memories of working on my very first Extreme Programming (XP) team.
In early 2001, I took charge of a large-ish team that was just starting to build a new and exciting system for a Fortune 50 financial-services client. I had been reading about XP for much of the previous year and had dabbled with some of its practices. But on this effort, we decided (and received management’s blessing) to do “full-on” Extreme Programming. We moved to an unoccupied space on the ground floor of our building where we set up our team area, and we did our best to follow all 12 of the XP practices “by the book.” (Well, we didn’t really try that hard with “Metaphor,” so make that 11 practices.)
Despite coming on the heels of the September 11 terrorist attacks, the initial release of the product was successful, which led to three subsequent releases of related systems built on the same platform. Because of this, we were able to keep the core of the team largely intact for the next couple of years, and we developed a pretty effective implementation of Extreme Programming that served us well.
Certainly XP doesn’t have all of the answers. Certainly it is not a be-all end-all process that is sufficient—or will even work—in every situation. Even Kent Beck (the author of the original Extreme Programming book) now promotes a different set of practices than what we were using. But in putting together and participating in this team, I learned a set of lessons which have served me well, and for which I am very grateful.
Here are a couple of those lessons that I learned from my first XP team—lessons that continue to have broad applicability for solving a host of software-development issues.
Have work come to the team, and not to individuals. This is probably one of the hardest things for managers of development teams to adjust to. There is magic in teamwork, but it doesn’t just happen naturally. If you truly want the team to work together as a team, then give the work to the whole team. Don’t assign individual tickets to individual people and don’t micromanage the individual tasks. Let the team figure out the “who” and “how” of getting its work done.
Measure and reward at the team level. Good software isn’t built by individuals, it’s built by multi-disciplinary teams. Completing even a small increment of useful software requires the skills of multiple people working together. The most meaningful metrics therefore focus on the team’s collective output. Don’t try to derive story points per developer; rather, expect the team to be able to get about as much done next iteration as they did in the last one. Also, don’t single out individuals team members either for praise or punishment. (Let the team itself take care of the low performers—they know who they are.)
Work in small, atomic increments. The technique of “growing” a system by adding small piece upon small piece is one of the most powerful lessons I learned. Done poorly, this will result in a “Frankenstein” codebase; done well and with the right accompanying techniques, it results in a thing of beauty. Whenever someone tells you they can’t work incrementally for whatever reason, challenge that assumption. If you have more than an hour or two, you can build something of value that is visible. If you have two weeks worth of a team of five, that’s over 400 hours.
Demonstrate your work often. Nothing eases fears and builds trust in a software development effort more than being able to see the working software as it evolves. Yes, it does incur some overhead to set up deployment environments and meetings and test scripts to make it easy for the consumers of the software to be able to touch it, test it, and try it out; but this overhead is more than compensated for by the increased feedback, communication, and sense of joint momentum. Remember, the software is not real to them until they can play with it themselves.
Constantly revisit your options. This is where a construct like user stories becomes so powerful. Used properly, user stories give the team and the customer lots of choices about what to build next. Stories do help us to plan and to make commitments, but at the end of the day they are about helping us to stay flexible and constantly ask ourselves, “What’s the right thing to build next?”
Harness automation to lower the cost-of-change curve. If the cost of making changes becomes too high, the overhead of working incrementally will eventually consume the team’s ability to make forward progress. You can get away with testing manually up to a certain number of features, but after that it becomes impractical to regression test everything each time a new story is complete. The same could be said of integrating code, or building to a test server, or deploying to production, or even setting up a new development machine. You need to be able to do the right things over and over again at low cost, and the only solution for this is a heavy investment in automation.
Visualize your work at all times. Even if you are required (or choose) to use a tool like Jira, you should create some sort of physical status board for the team to use in its hour-by-hour and day-by-day collaboration. There is nothing like good old-fashioned index cards and post-it notes for easy manipulation and updating, and nothing radiates status more transparently than the walls of the room where the team is sitting.
Have the team sit together. A co-located team always out-performs one that is spread out physically. This is a lesson we don’t want to believe, but I keep seeing it an experiencing it first-hand. It turns out that optimizing communication and collaboration speeds things up a lot more than almost anything else you can optimize on a software project. When people have something important or crucial to accomplish together, they naturally gravitate towards working in close physical proximity. It is possible to compensate in many ways for not being physically co-located, but it is very difficult to replicate.
Work in constant, fixed-time increments. Yes, I know that there are successful Kanban teams out there who have freed themselves from the constraints of the “arbitrary time box.” But there is nothing like a short iterative cycle—two weeks, anyone—to help the team get into a regular rhythm, learn to prioritize, measure their capacity, learn to make and keep commitments, and ease the customer’s mind about the rate of progress.
Pair program to spread knowledge. Yes, it’s harder than programming by yourself, just like working out with a personal trainer is more exhausting than the way you’re likely to work out on your own. But as with exercising, effective pairing yields fruits that last well beyond the moment—better quality, better designs, increased cohesion, and a much deeper shared understanding of the code, to name a few.
Swarm on stories. Multiple people working on stories at the same time is another way to optimize communication across the team and get the benefit of multiple brains looking at a problem. Stories can almost always be broken up into smaller tasks, which can be worked on in parallel by multiple sets of people. Think long and hard about letting any individual on the team “own” a piece of work exclusively.
Believe that quality is free. Every investment I have ever made to improve the quality of our software is an investment that has paid for itself within a few weeks or months. I have never regretted taking time to establish the infrastructure for automated developer tests or automated functional tests. I’ve never been ashamed to ask everyone on the team—despite their role—to test daily. The cleaner the code, the fewer the known defects, the more everyone benefits. As the lean community says, you really do have to go well in order to go fast.
There were other lessons, as well. But this is a good summary of the ones I keep returning to over and over again. Stepping back and looking at the list, it seems that I just re-derived many/most of the principles from the Agile Manifesto. And that’s how it should be. Any good instantiation of an agile process (such as XP) should lead you eventually to appreciate he underlying principles that are at play.
Like others, I have found these principles to be broadly applicable to many software development situations. And that’s why I keep coming back to them.