Week 2: Scheduling and Coordinating the Work

Continuing the "Getting Started" series.  My team just finished our second week.  Luckily enough we were able to get through release planning quickly and start Iteration #1 on Tuesday.  CruiseControl.Net is up and running.  I kept a list of the topics that came up this past week that I might want to talk about in the blog, and a single theme pops out:  how to schedule and divide the work.

First, some little things:

  • Check in code often.  Constant check-in's should keep the overhead of merging to a minimum.  Continuous Integration is an attitude, not just a tool.
  • Work in small steps.  That means write a unit test's worth of code at a time.  The TDD red bar should be a short phase and there really shouldn't be many times when the code can't compile for more than a few minutes.  Working in big chunks without verification is what brings out the inefficient, marathon debugger sessions.
  • If you're helping a team learn TDD from scratch, don't let them start early with dynamic mocks.  Let them get a handle on TDD with work that leads to state based testing first.
  • When you're doing TDD, try to break the work into small tasks.  From that task breakdown, think about how each task or step could be tested.  Your low-level design pretty well follows from testing one task at a time and building up to the whole.  Code from the bottom up!
  • Build business functionality first, and let the infrastructure come second to enable the business functionality.  I tried to avoid this, but it happened anyway.  We got a bit caught up in UI infrastructure and didn't get much functionality built.  The danger of focusing on infrastructure solely upfront is the risk of getting tied down in purely speculative coding that doesn't deliver any value in the end.
  • Check in comments!!!

 

Iteration #1 Work

I think the real goal of iteration #1 is to create knowledge more so than code.  You will never produce as much functionality in iteration #1 as you should in later iterations.  The first iteration almost has to be concerned with creating a common vision of how you're going to build the software, especially if the team hasn't worked together before.  You could lay your ears back and code away at full speed, but you'll pay for it later with either technical debt or longish design sessions with the rest of the team explaining (and arguing about after the fact) the technical approach.  I sincerely believe that people understand design strategies far better when they have been present for the formulation of that design strategy.

I say this mostly to try to alleviate the stress from first iterations when the code isn't flying off your fingers into the IDE.  When you're loading up the first iteration you really shouldn't count on doing as much "work" as you will later on.  I think this is in line with Eric Evan's idea of Knowledge Crunching.

Splitting the Work

I've seen two real issues this past week:

  • The beginning of the project is much rougher for merge conflicts than it will be later on in a bigger code base.  Strive to find stories that can keep the multiple pairs out of each other's way.  Even so, it still takes a lot of communication around work on shared or foundational classes.  A simple "hey, we're about to rename this class.  Is that okay with you?" goes a long, long way to alleviating the worst of the merging issues.
  • Rotating people through different areas of the work.  Like I said in the previous section, I'm more concerned about creating the shared understanding upfront than cranking out code right now (on the theory that this shared understanding will pay off immediately in the following iterations).  We're just trying to be cognizant about rotating people through different kinds of story work.  It's a bit incumbent upon each developer to speak up when they think they're getting siloed.

Serialize the Work

For best results, you should focus your efforts on completely finishing active stories before starting any coding work on new stories.  You should only start coding work on a new user story if you're completely blocked or out of work on the previous stories.  First you really do have to internalize the idea that the development team as a whole can only take credit for production ready code.  Once you do that, which outcome at the end of an iteration below is better?

  1. 5 out of 10 user stories scheduled for the iteration are production ready.  3 of the others have not been started. 
  2. All 10 stories for the iteration are in some sort of intermediate state. 

Even though both outcomes may reflect the same amount of effort by the developers, only outcome #1 provides any real business value.

You also need to get something in the hands of the testers or reviewers by at least mid-iteration if you're going to make your iteration.  Besides, the human mind just doesn't handle context switching all that well.

Ordering Stories

XP dogma states that you order the user stories in terms of business value.  In practice I've never found that to be enough.  There's always constraints of some sort that have to be accounted for in your schedule:

  • What stories are understood well enough to work on?  You're going to need to look ahead a bit to make sure you always have enough stories ready to go at the start of each iteration.
  • Does one story depend on some infrastructure that's built in a different story?
  • What stories can be worked in parallel?  If having two or more stories involve the same area of code, you may want to serialize these stories to prevent some nasty merges.
  • Eliminating risk.  This might be technical risk of some sort, but it could also be business risk.  Our project is user interface-intensive.  One of our best ways to reduce risk is to get the user interface in front of the client as soon as possible to make sure the UI is acceptable and meets the business needs.
  • External constraints.  You're almost always dependent upon external groups or even external companies.  You simply cannot do work that depends on a different team without coordinating with them first.  We're going to try to get some representation from the server side team in our iteration planning meetings to deal with this coordination.

Breaking up Stories

Don't hesitate to break stories into small units.  For example, there isn't any rule that says you have a one to one relationship between a screen (especially a complicated screen) and a user story.  As long as a user story provides some amount of business value and can be tested by itself, it's fine.  Smaller stories are easier to estimate and drive to completion.  Dividing the work into smaller chunks helps to get working code in front of the users and testers earlier in the iteration to make their jobs easier.

What I don't feel good about are stories like "Capture the information in the screen" paired with "Persist the information to the database."  Capturing the information in the screen is just a task.  It doesn't really provide any value until it really works from end to end.  Dividing the work into "Capture header information" and "Capture details" and maybe even "Validate the user inputs" into separate stories is much more acceptable to me.

Can You Have Technical Stories?

I say preferably not, but it's not the end of the world.  As long as the stories are very focused into a specific technical task to enable the following business stories, I'm fine with technical user stories.  I've often found it easier to pull out a shared technical dependency of multiple stories into a technical story for easier tracking.  What's definitely bad are stories like:  "Create the Data Access Layer" or "Create the Model View Controller Framework."  Those stories are black holes.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Continuous Integration, Pair Programming, Starting a new Project, Test Driven Development. Bookmark the permalink. Follow any comments here with the RSS feed for this post.