Sunday, April 11, 2010

Cross-Functional Teams

We're trying out a new idea that I'm excited about: cross-functional teams.  Our group has expanded slowly and organically over the years.  As we've needed more programmers, we've hired them.  As we've needed more testers, we've hired them.  But now we're almost 20 people strong, and we're hitting the limits of a productive team size.

I'd been unconsciously steering us towards separation by task: the product managers pass their ideas to programmers, who write the code and pass it off to testers, who test it.  But that becomes harder and harder to coordinate as the number of projects and people grow -- without domain separation, everyone needs to know everything about every project.  And that's both unscalable and unproductive.

So we're trying out the idea of cross-functional teams: three groups comprised of a few coders, a tester, a product manager, "half" of a project manager, and one or two designers.  I see this as having a few benefits:

  • It will reduce task switching.  People will be able to concentrate on one of a few different projects assigned to their group.
  • It will let everyone more effectively embrace the business goals expressed by the product managers.  Instead of getting sent in a different direction with each new project, people will hopefully be able to internalize a larger set of goals and apply them automatically to each project.
  • It will make communication easier by limiting the number of people involved and letting people develop deeper relationships than they could with a larger group.
I'm really looking forward to the benefits this change should bring, and will keep everyone posted on how it goes.

Lean Software

I recently finished a short, insightful book called The Art of Lean Software Development.  It connects the principles of lean manufacturing with those of agile software development.  It's a fascinating path: lean manufacturing started with Toyota decades ago, and focused on obsessively ridding systems of "seven deadly wastes:"
  • Defects
  • Overproduction
  • Transportation
  • Waiting
  • Inventory
  • Motion
  • (Over)Processing
(These can be abbreviated to "DOTWIMP" if you're ever quizzed on them.)  Most of them are self-explanatory if you consider the additional costs they could bring to the car manufacturing process.  "Motion" refers to the idea of people or machines moving around -- if you can find a way to avoid it, you're better off.  "(Over)Processing" means doing anything that's not required by the customer.

It's interesting to apply these to software, as the book does, and find corollaries:
  • Defects => Bugs
  • Overproduction => Extra Features
  • Transportation => Handoffs
  • Waiting => Delays
  • Inventory => Partially Completed Work
  • Motion => Task Switching
  • (Over)Processing => Unneeded Processes

As with a lot of discussions about process, it's easy to write all this off as common sense.  And yet we can all get mired in processes and miss the forest for the trees.  It's always insightful to step back and use a list like this to get a fresh perspective on what's working and what needs fixing.

I find a lot of people (including myself) trying to apply software development processes without always thinking about the overall idea: they have daily standups, planning meetings, workflow charts, etc.  It's easy to think that just going through the motions of these steps will help you.  And in some cases, it does.  But it's important to constantly challenge your assumptions.  Holding yourself accountable to eliminating these "deadly wastes" seems like a great way to do that.

Faster Codebases

Continuing with the idea of code design and productivity, a colleague recently shared some keen wisdom: "Creating an agile team begins with an agile codebase."  As the last post discussed, productivity and code design are clearly related.  What's interesting is to expand this idea to the entire spectrum of agile development.

Many of agile's mainstays -- quick iterations, releasable software, and continuous integration -- all require a codebase that makes these possible.  And that goes back to two main ideas: de-coupling and encapsulation.  Those principles, in turn, make the following goals a lot easier:

  • Simple, effective unit tests (tight coupling leads to brittle, cumbersome tests that are really integration tests)
  • Easily deployable software (tightly coupled code is hard to deploy without breaking other parts of the system)
  • Team scalability (a team can't grow quickly if each member has to intimately understand the entire codebase)

I used to think re-factoring was a process that could happen slowly in parallel with business goals.  But now I realize it needs to be an end in itself, in order to support not only productivity, but a growing team and an agile environment.