Headshot-color me@jbrains.ca Find out where I'm appearing
« Previous 1 3

Three Steps to a Useful Minimal Feature

Recently, in the mailing for Steve Freeman and Nat Pryce’s book Growing Object-Oriented Systems Guided by Tests, I followed a discussion that included this comment:

I guess the skill is knowing in what makes as small as possible but valid slice (as you say in the book)

Even though I’ve written before about splitting stories, I have refined my ideas about how to deliver a useful, significant, but small slice of software. I use a simple technique which I describe this way:

  1. Write out any, and I mean any, meaningful end-to-end scenario in detail with concrete values at every step.

  2. Now that you’ve chosen one real scenario, go to each step in that scenario and ask the question, “What would I need to assume to eliminate this step?” If you find those assumptions make for a reasonable scenario, then use that assumption to simplify the scenario.

  3. Repeat step 2 until exhausted or unable to come up with a simplifying assumption with five minutes’ thought.

I’ve used the example of online bill payment in many of my classes and applied this algorithm. You’d be surprised how simple, but useful a bill payments system one can build.

In fact, let’s look at this example in a bit more detail.

What does a typical bill payments system look like? I imagine that TD Canada Trust has a fairly representative system, so I’ll use that as my example.

First, select the “Pay Bills” option.

Selecting Pay Bills

Next, select the account to use to pay the bill.

Selecting the account

Next, select the bills you’d like to pay. Once in a while, I want to pay multiple bills at once, such as when my business has to pay the property taxes on a handful of rental properties.

Selecting the bills to pay

Next, enter the amount you want to pay, the date on which to pay it, the account from which to pay it (why again?) and whether you want to repeat this payment automatically.

Entering the details

Verify the payment details: the amount, the account, the creditor, the date, and the system schedules the payment.

Verifying the details

From this, I can describe the scenario in a form that looks like an executable example:

Pay a bill online

  • Given that Joe has already logged in
  • Joe says "I want to pay a bill"
  • Joe selects chequing account 12345 from which to pay the bill
  • Joe selects Visa bill with account ending in 2222 as the bill to pay
  • Joe says "I want to pay $5,000"
  • Joe selects a date 14 days from now as the date on which to pay the bill
  • Joe selects "only once" as the frequency with which to pay the bill
  • After Joe sees a summary of the bill payment he has asked to schedule, he says "I confirm that I want to pay this bill"
  • Now the system schedules to pay the bill as requested and sends Joe an email to confirm the transaction with a link to cancel or change the scheduled payment

Apart from the numbers, this scenario perfectly accurately reflects how I pay my bills online, although I only wish TD Canada Trust would send me the confirmation email I threw in as the system’s response. We have completed step 1 of the algorithm: we have specified a complete scenario with concrete values at every step.

You'll notice that we didn't specify Joe's username and password. We don't intend to re-test logging in here, so we don't bother with those details. We will have tested that elsewhere.

Now we move to step 2 of the algorithm: looking for assumptions we could make about paying a bill online that would eliminate steps in the process. To do this, we have to be prepared to sacrifice any semblance of a decent user experience. Don’t worry: once the Walking Skeleton runs, you’ll be able to add all the bells and whistles that will make this feature a pleasure to use. For now, we want to eliminate any detail that distracts us from connecting our feature to the key interfaces it must deal with. In this example, I know I want to expose an HTTP interface to clients (eventually the web) and that I need to connect to the Big Ugly Banking System, but beyond that, I don’t know that anything else matters. Within this context, then, we can start making our simplifying assumptions.

That is, until someone remembers that, being a bank, we need to keep a strictly accurate record of all transactions. That means we should add a final step to the scenario: the system records the transaction in its log. While some might consider this a superfluous detail, banking regulators would call it quite essential, and so I find it hard to ignore. This means that we have a third essential interface to which to connect: the transaction logging facility. For our purposes, I’ll assume that we have one and that it has the usual properties: transaction posting date, description, and debit or credit amount, who performed the transaction and when.

This itself makes me ask whether we need to log the transaction yet, because in our scenario we’ve scheduled a payment, and not made one. Scheduling a transaction leads to issues of canceling, editing, and building a process that completes the transaction on the day the customer scheduled it. This leads to our first simplifying assumption: Joe pays the bill immediately.

This simplifies the scenario because we no longer need Joe to tell the system when to pay the bill: the system always pays the bill immediately. Our revised scenario looks like this:

Pay a bill online

  • Given that Joe has already logged in
  • Joe says "I want to pay a bill"
  • Joe selects chequing account 12345 from which to pay the bill
  • Joe selects Visa bill with account ending in 2222 as the bill to pay
  • Joe says "I want to pay $5,000"
  • Joe selects "only once" as the frequency with which to pay the bill
  • After Joe sees a summary of the bill payment he has asked to schedule, he says "I confirm that I want to pay this bill"
  • Now the system schedules pays the bill as requested and sends Joe and email to let him know that the bill was paid

I like to start at the top and look for simplifying assumptions. First, I see that Joe has to select the account from which to pay the bill, which implies that the system presents a list of accounts to Joe, which we recognize we need to do, but not in the Walking Skeleton. Ultimately, Joe simply needs to specify the account number to debit to pay the bill, so for now we’ll make him type that in. Our revised scenario looks like this:

Pay a bill online

  • Given that Joe has already logged in
  • Given that Joe has already logged in
  • Joe says "I want to pay a bill"
  • Joe says "I want to pay from account 12345"
  • Joe selects Visa bill with account ending in 2222 as the bill to pay
  • Joe says "I want to pay $5,000"
  • Joe selects "only once" as the frequency with which to pay the bill
  • After Joe sees a summary of the bill payment he has asked to schedule, he says "I confirm that I want to pay this bill"
  • Now the system schedules pays the bill as requested and sends Joe and email to let him know that the bill was paid

Next, I see that Joe again has to select the bill to pay, which implies that the system presents a list of bills to pay. We could simplify this by requiring Joe to enter the payee identification number and the account number, even though this means saddling Joe with knowledge of payee identification numbers. In particular, the system neither has to store nor present a list of bill payees, and Joe doesn’t need to register a creditor before paying them.

I'm making up this notion of payee identification numbers because I don't know how banks really implement this. I imagine whatever they do, it boils down to companies registering as payees for bill payments, which results in issuing them some kind of identification number. If some kind soul wants to educate me on how this really works, I'd gladly edit the article to bring it closer to the banking industry's real implementation.

Our revised scenario looks like this:

Pay a bill online

  • Given that Joe has already logged in
  • Given that Joe has already logged in
  • Joe says "I want to pay a bill"
  • Joe says "I want to pay from account 12345"
  • Joe says "I want to pay to payee number 66666"
  • Joe says "I want to pay to account number 2222"
  • Joe says "I want to pay $5,000"
  • Joe selects "only once" as the frequency with which to pay the bill
  • After Joe sees a summary of the bill payment he has asked to schedule, he says "I confirm that I want to pay this bill"
  • Now the system schedules pays the bill as requested and sends Joe and email to let him know that the bill was paid

Next, I notice that Joe has to specify the amount to pay, and I can’t think of how to eliminate that detail without complicating matters. It does make me think about potential future features, such as “pay balance off in full” and “pay minimum payment required”, which I note down before returning to this scenario. Joe will simply have to tell us exactly how much to pay towards the bill.

Next, I notice that Joe has to confirm that he only wants a one-time payment. We can eliminate this detail by assuming that Joe can only pay the bill once. We know that customers want recurring payments, but that only distracts us from implementing the Walking Skeleton. We can eliminate this step, and our revised scenario looks like this:

Pay a bill online

  • Given that Joe has already logged in
  • Joe says "I want to pay a bill"
  • Joe says "I want to pay from account 12345"
  • Joe says "I want to pay to payee number 66666"
  • Joe says "I want to pay to account number 2222"
  • Joe says "I want to pay $5,000"
  • After Joe sees a summary of the bill payment he has asked to schedule, he says "I confirm that I want to pay this bill"
  • Now the system schedules pays the bill as requested and sends Joe and email to let him know that the bill was paid

Next, I notice that Joe has to confirm the bill payment before the system will process the payment. While this step might seem essential for security reasons, remember that we don’t necessarily have a graphical web interface for our Walking Skeleton implementation, and so we might not even have the opportunity to ask for confirmation of the bill payment. On this basis, we eliminate this step by assuming that Joe has looked over the details before pressing the button to pay the bill. Our revised scenario looks like this:

Pay a bill online

  • Given that Joe has already logged in
  • Joe says "I want to pay a bill"
  • Joe says "I want to pay from account 12345"
  • Joe says "I want to pay to payee number 66666"
  • Joe says "I want to pay to account number 2222"
  • Joe says "I want to pay $5,000"
  • Now the system schedules pays the bill as requested and sends Joe and email to let him know that the bill was paid

I can’t see any further simplifications, so I choose to stop here. I suspect this constitutes a close-to-minimal protocol for the “pay a bill online” feature. The programmer in me sees this as a single message, which pleases me, because of the simplicity of the interaction. The customer in me can see clearly all the extra stories we need to complete to make this feature available for public use, which makes planning easier. It feels like a win for everyone, except perhaps for Joe, who has a crappy interface to work with.

Now that we have a Walking Skeleton bill payment feature, we can identify the stories we want to deliver beyond the simplest case, and can decide which ones we need to roll this feature out to paying customers.

  • Let Joe choose from a list of available payees which company to pay
  • Remember the payees that Joe has previously paid and present them as “favorites” so he doesn’t have to search for them
  • Remember the payee accounts that Joe has previously paid so that he doesn’t have to enter them each time
  • Let Joe delete accounts he no longer needs to pay
  • Give Joe the option of paying the minimum payment required by the payee
  • Give Joe the option of paying the full balance owing
  • Let Joe schedule his payment in the future
  • Let Joe cancel pending payments
  • Let Joe change pending payments
  • Send a reminder to Joe to pay a bill he has paid at least three of the past six months (try to detect a recurring payment)
  • Let Joe schedule a payment to recur every month (same day each month)
  • Notify Joe in advance of automatically detected recurring payments and ask him if he wants us to pay the bill for him
  • When emailing Joe about a bill payment, include links to review the scheduled payment, change it, or cancel it, if appropriate

I imagine we could come up with more together, but I find one common thread with all these stories: once we implement the Walking Skeletion, we can implement most of these stories independently of the others. We know that more independent stories means greater opportunities to change priorities as needed as well as greater opportunities to drop features in favor of other more lucrative options. Once again, everyone wins.

Would you like to work with J. B. Rainsberger to realize revenue sooner and lower costs from delivering software? Schedule a workshop with J. B. today.

July 16, 2010 08:00 stories, planning, design, article

Toddlers, novelty, and planning

I visited a dear friend this week and had the chance to meet her young son for the first time since before he turned one year of age. I believe he turned four years old this year, and I got to watch him ready himself to leave his pre-school program. Since Toronto still has winter, Kieran had to negotiate a coat, snow pants, boots, mittens, and all the while he was greeting and saying goodbye to his friends, running around getting some additional exercise, and just generally living in the moment. I don’t remember how long it took to leave the building, but it took some time. Melissa turned to me and remarked at how slow toddlers move. I disagree.

A toddler looks slow, but doesn’t move slowly at all. On the contrary, they move quickly from idea to idea, input to input, person to person, thread to thread, processing a ton of information. Novelty dominates the toddler’s life, robbing them of the opportunity to focus, as they dart around to every new piece of input. Their apparent speed, then, comes not from moving slowly, but from trying to do everything at once, responding to novelty and generally having no real plan.

I simply found that interesting. No connection to software. (Wink)

The perfect item for your team room...

…if your project is a death march.

June 03, 2008 03:00 agile, people, planning

Backpack helps me change my habits

I use Backpack to help me change my habits for the better, and I wanted to share this little technique with you.

The programmer in me values version control systems because they allow me to keep an indefinite record of what I’ve done. If something goes wrong while I’m working, then I can go back to an old version of a file and continue working. This is why I use Mercurial every day.

The entrepreneur in me values off-site backups because if a fire destroys my office, then all I need is any computer and an internet connection and I can get back to work. This is why I use Amazon S3 every day.

The scanner in me values getting things done, because when commitments start to sneak up on me, I have my commitments, actions and priorities in one place, and I can get back on track. This is why I use OmniFocus every day.

What I’ve noticed, though, is that my tasks aren’t really getting done. For me, most tasks require building or changing some key assets. Sometimes that’s code, or expense receipts, or drafts of an article. It’s not good enough to write the article, I want to put it into version control and know it’s backed up off site. It’s natural for me to end a coding session by committing changes to Mercurial, but it’s not yet natural for me to end a non-coding work session the same way. I need to remind myself to do this.

Whenever I hear myself think or say, “I need to remind myself…” I immediately log in to Backpack, because it does such a great job of reminding me of things. Today, I added a reminder that reads

A task isn’t done until the assets are safe: under version control and backed up

I set the reminder for tomorrow, and every day after that, until the idea is burned into my brain and becomes second nature. I’m not sure how long that’ll take, but by this time next month, I should be able to switch that reminder to every month, just to make sure it doesn’t fall completely off my radar.

This is how Backpack helps me move away from bad habits and move towards better habits.

January 04, 2008 17:22 people, planning, being a scanner, emotional health

Forget velocity

What does velocity measure?

First, let’s be clear: by velocity, I mean story points delivered per iteration over time. Of course, that means we need more definitions, so let me get those out of the way now.

“A story point” is a unit that programmers invent solely to make it easier to estimate the work it takes to deliver a story. A story point is however big the programmers decide it is, no more, and no less. Story points are useful to the extent that they help programmers compare the effort required to deliver different stories, so that the team can decide how many stories to commit to delivering in a given iteration. Although story points necessarily fluctuate in value, one hopes that over a sufficiently short span of time – say the length of a release – the fluctuation is small enough that a constant approximation of velocity is helpful enough to plan the release.

“Delivered” means realizing (in the accounting sense) the value the customer intended to realize by asking the team to work on the story. A story is not delivered until it either reduces cost or generates revenue.

“Iteration” means equal-length time boxes the goal of which is to provide natural breaks in daily work to reconsider the plan and stop work from expanding indefinitely. On teams that have less trouble stopping when they’ve done enough, iterations are less important.

“Over time” refers to the trend of spot measurements over at least the length of a release.

I hope that makes it crystal clear what I mean by velocity. Now that I’ve clarified the meaning of velocity, what does it measure? It simply aggregates past estimates of effort of a set of stories the team selected to complete in the last several iterations. That doesn’t sound like much, does it? There’s more. Here are some things that velocity does not measure:

  • productivity
  • efficiency
  • value
  • suitability to re-hire or retain

…and, of course, past performance does not guarantee future results. Read your prospectus before investing. If velocity is so meaningless, then why measure it? Well, it turns out that:

  • It is a good approximation (accurate about 2 times in 3, we think) of what the team can commit to in the next iteration
  • It is a good approximation (we think) of what the team can commit to over the next handful of iterations (say 4-6)
  • It is a good approximation of when the current stack of work we’ve identified will be done, as long as the stack of work isn’t too large (up to about 4-6 iterations’ worth)

I have just witnessed a conversation on the extremeprogramming Yahoo! group that illustrates the knots in which we tie ourselves when we allow ourselves to be too imprecise about what a measurement measures. The whole thing puts me in mind of personal financing and when budgets don’t work.

Think about budgeting your expenses at home: you know how much you actually pay for some expenses, like car payments, mortgage or rent, insurance… the amounts you owe are usually spread out over such a long period that you can anticipate what you’ll owe next month with certainty. Moreover, you know that it takes concerted effort on someone’s part, or human error, to change the amount you owe on a mortgage, car loan or your home insurance. Changes in those amounts, at least correct ones, generally don’t sneak up on you.

There are other expenses that vary from month to month: food, clothing, entertainment, communications… the amounts you owe usually depend on how much of a given resource you consume, such as how much you eat, how much you talk on the phone and how stressful your work is that month. You can budget these amounts fairly accurately, because the variation is low enough and mostly under your control: you can choose to eat less, take better care of your clothes, read more library books and rent fewer movies. Not only is it easier to guess what you’ll spend in a given month, but if you start spending too much, you can easily correct course to spend less.

There are still other expenses that you just can’t foresee. You are injured in an accident and rack up $20k in hospital bills; this is the year out of the last ten that you finally need new shingles on the roof; you find out your son needs braces. You might buy insurance as a way of smoothing out the costs over time, but they are generally big expenses that you know are coming in the larger sense, but which arrives without warning and needs to be paid immediately.

These are the expenses that make budgeting not work, because they prove that there’s no such thing as a typical month. This is also why you cannot rely on velocity to plan far ahead: there is no such thing as a typical project or even a typical iteration. If velocity doesn’t bring a project under control, then what might? For an answer, I invite you to consider personal finance again.

I read Your Money or Your Life to help me bring my personal finances under control and become financially free. One of the key exercises the book asked me to perform was to track all money coming in and out of our household for several months. This exercise is designed to call attention to our spending habits, so we can decide what to do about them. In particular, we identified those expenses we valued and those we didn’t value, so we could stop spending money on things we don’t value. This tactic, spending money only on things we value, doesn’t necessarily make one rich, but it ensures that one is not wasting money on things one doesn’t actually value. You’d be surprised how much money we were throwing away on things that didn’t ultimately make our lives any better, and you’d be amazed at the results when we stopped: we used that money as capital to generate passive income, and within five years, we’ve become financially free. But I digress. The point is what we measured, then how we analyzed it.

We measured actual spending, rather than estimated future spending or even estimated past spending. When we had the numbers, we didn’t start slashing expenses we cared about, and we didn’t start looking for cheaper alternatives to all our expenditures. Instead, we simply looked for those expenses we did not value, then cut them off. In some cases, this required investment of money: we bought a coffee grinder, an AeroPress, then started brewing coffee at home, rather than spending $2 per on coffee at our local coffee shop. In some cases, this required investment of time: we reviewed our work commitments and changed the way we work so that we wouldn’t be so tired so often, which meant we no longer “needed” to order dinner in as often as we did. We measured our actual spending, we looked at those numbers to identify waste, then we eliminated it. We did not waste effort staring at our budget, wondering how accurate it was, wondering how realistic it was, desperately trying to spread not enough money over too many expenses. We didn’t have to: we had actual expense numbers and could decide which items we valued and which we didn’t. More to the point, this exercise was far more instructive and effective than budgeting ever was.

Does your company value the areas where your software team spends its money? Do you know how to measure the value of what your team produces? How much money (time, energy, or actual cash) does your team spend on things no-one values? Could you pick three such wastes and eliminate them? What would you do with the recovered time, energy, or cash? How would you know that things got any better?

Forget velocity for the time being. Measure it and report it to whoever still wants it, but just between you and me, forget velocity and focus on these key questions. Try it for a few months. Share with us what happens. I’d love to hear from you.

« Previous 1 3