The flow of team software design

This week, I taught another installment of Headspring’s Agile Boot Camp, part 2.  On one of the days, I lead the team (class) through a team design session to add some rather involved behavior to the software system used in the class.  I started out by putting on my customer hat and laying out the release objectives.

When attempting to get everyone on the same page, visuals are very important.  Either whiteboard, chalkboard, paper, or anything visual will do.  Here is a picture of the release goals written out.  I invited the team to ask me clarifying questions about the goals.


The top three, we pulled out as stories and put them on our story wall.  The next three were cross-cutting business rules that applied to the three stories.  The team quickly complete the first story and then split up the next two. 

Before the team began test-driving the functionality through pair-programming, we conducted a team design session to get everyone on the same page.  We did just enough drawing to ensure that everyone had a meeting of the minds.  In reality, if team members start slinging code before everyone has a shared understanding of the approach, there is bound to be wasted work.  Individuals will create assumptions and act on them.  Then, when the assumptions are invalidated, we also have work that becomes invalidated.  This is waste, and you never get that time back.  A little bit of communications (meeting of the minds) goes a long way to ensuring that the work done is the right work. 

We started the design session by coming up with all the individual responsibilities that are necessary to satisfy the stories.

The blue initials next to each responsibility is the acronym for the interface that has been assigned the responsibility.  After responsibilities had been identified, we took to the whiteboard and created a sequence diagram using the chosen type names.  This allowed us to determine dependencies and flow.

There are actually two different threads present on this sequence diagram.  On the left, the state command initiates a notification that gets placed into a queue.  On the right, a queue watcher peeks at the queue (intended to be run with Windows Scheduler) and kicks off the sending process according to business rules.

There are only certain state transitions when a notification needs to be send.  This is visualized through a state diagram:

The most hairy part of the design is the IQueueWatcher implementation.  This deserved its own graphic, and there was lots of discussion while we were fleshing out the flowchart.

Even as crude as it looks, the act of creating this as a team caused each team member to think critically about how the feature needed to be implemented.  There are lots of different places in code where a decision can be made, and putting it in visual form solidified the approach across the team.

The last step before actually pairing up and hitting the keyboards was to task out everything that needed to be done.

Notice that the first task was to create all the interfaces and common types.  By doing this first, other tasks could be accomplished without being blocked by uncompleted work.  One pair can work on the calling side of an interface, and another pair can work on the implementation.  Interfaces are natural seams, and when used liberally, provide a natural decoupling.  This decoupling enables team development while still working closely on the same stories.  My experience has shown that collective code ownership falls in line naturally when using this approach.

At the end of the day, the team hammered through the stories very quickly because each class by itself was very, very simple.  I really enjoyed the class, and I look forward to teaching the next Agile Boot Camp.