Thursday, June 7, 2012

Making Implicit Use Cases Explicit

If I could attach a number to something, it would be how many implicit use cases materialize during the development phase of any given project. They outnumber the explicitly spelled-out use cases. It's a little difficult to define what, exactly, an implicit use case is. Is it all the valid use cases of the system that were just overlooked? Do use cases include malicious intent by the user?

The trouble is, use cases generically capture the intended usage patterns by users. The user wants to get to point C, so we need to get them through A and B. And this works because it explicitly states the what. If we have a collection of these generic use case statements, we can use them to ensure we are in fact solving the problem we've set out to solve. But when new software is crafted, new problems are introduced — new opportunity for miscommunication and human error.

What happens is the implicit use cases that went unnoticed saturate the design and any code written. Not only do you have to deal with these cases when they're inevitably discovered, but you're also taking a mental hit. Finding missed cases when you think you've got it all covered hurts morale. This is no different from the waterfall approach — when big upfront design fails, it fails hard. Explicating all possible use cases isn't feasible either. This is almost waterfallesque, trying to foresee the unknown. Perhaps a better organizational schema for tackling the problem of implicit use cases is to group them by personae.

Generic Use Cases
The practical aspect of use cases is they capture a generic scenario. For any given function of the system, we can make statements about what that functionality looks like from the actor's point of view. And they're the same for all actors. So we have this relationship between an actor, also generic, and a use case. This says that we can reasonably expect a certain commonality across the users of our software. This assumption is necessary, because you can't sit down with each individual that plans on using your software, interview them, draw up the use cases based on their personal preferences, and make the corresponding code modifications. Practicality dictates that we come up with a template. One that best represents why we're building what we're building.

Generic use cases are challenging enough to manage, even with the reduction in complexity due to common user expectations. Imagine that your software's user-base were all clones of the same person with the same personality traits, the same knowledge of your application, the same everything. With this in mind, you could simply go about documenting how these clones would go about interacting with your application. Every situation presented to them would prompt the same response. So with the human variables removed, you're free to focus on the use cases themselves, and avoid the relationship between the actor and the use case.

By and large, this is how we design software today. We take the set of human clones and apply formulated use cases. We establish the generic link between actor an use case. The positive angle to this approach is that we can easily manage these relationships. Just like when you design a class hierarchy, you put the common structural and behavioral features near the top. This allows our brains to think generically, as opposed to having to specializations straight away. Use case definitions work in the same way — we focus on the top level of the class hierarchy, trying to document the common use cases for the common user. This is a good way to get started with the requirements of your system, but just as with class hierarchies, specializations must be put forward.

Specialized Use Cases
The generic, templated approach to use case design work is where implicit use cases originate from. Consider our group of user clones again. When they're using the application, everything is fine. But introduce another set of clones, based on a different individual, we start to see some interesting things happen. Because the generic use cases that our system is based on really only considers one persona, we can't accommodate another. Of course there is some level of overlap between the two groups of human user clones, and that is why we design use cases generically to begin with. But not everything overlaps. There are individual differences that need consideration.

The differences in user personae are the reason we require specializations in the use cases of our software. They're the reason why the relationship between between actor and use case are important.

To remedy this problem, we employ user experience design, as is the standard practice today. More often than not, the user experience design activity occurs after the generic use cases of our system has been captured and finalized. This is what our software will do, so let's make sure the experience of doing those things is pleasant for each personae. This works from a user interface perspective, but the improvements seldom end there. Whichever persona we're improving upon, will often require more than a simple rearrangement of user interface components. The changes in improving the experience for any software tends to trickle, top-down, into it's roots.

The generic approach to use case design is feasible, this is why we do it. My suggestion is that we take it one step further and think more deeply on the user experience design at this stage. User expertise at use case time, perhaps even before the user interface code exists, is invaluable. There are bound to be a few light bulbs that have far-reaching consequences in terms of how your code looks all throughout the system. You don't have to go about this histrionically either. Even two or three personae taken into consideration during use case discussions would help.