When Use Cases Aren’t Enough, Part 1

Karl Wiegers | November 29, 2012

Use cases are recognized as a powerful technique for exploring user requirements. The great benefit they provide is to bring a user-centric and usage-centric perspective to requirements elicitation discussions. The business analyst employs use cases to understand what the user is trying to accomplish and how he envisions his interactions with the product leading to the intended user value. Putting the user at the center is much better than focusing on product features, menus, screens, and functions that characterize traditional requirements discussions. And the structure that use cases provide is far superior to the nearly worthless technique of asking users “What do you want?” or “What are your requirements?”

As with most new software development techniques, use cases have acquired a bit of a mystique, some misconceptions, overblown hype, and polarized camps of enthusiasts who will all try to teach you the One True Use Case Way. In this series of three articles (adapted from my book More about Software Requirements), I share my perspectives on when use cases work well, when they don’t, and what to do when use cases aren’t a sufficient solution to the requirements problem.

The Power of Use Cases

I’m a strong believer in the use case approach. Users can relate to and review use cases because the BA writes them from the user’s point of view, describing aspects of the user’s business. In my experience, once they get past the discomfort of trying a new technique, users readily accept the use case method as a way to explore requirements.

I’m often asked how to write requirements specifications so that users can read and understand them and also so that they contain all the detail that developers need. In many cases, one requirements representation won’t meet both of these objectives. Users can comprehend use cases, but they might balk at reviewing a more detailed mass of functional requirements. Use cases give developers an overall understanding of the system’s behavior that fragments of individual functionality cannot. However, developers usually need considerably more information than use cases provide so that they know just what to build. In many circumstances, the combination of employing use cases to represent user requirements and a software requirements specification to contain functional and nonfunctional requirements meets both sets of needs.

Project Type Limitations

My experience has shown that use cases are an effective technique for many, but not all, types of projects. Use cases focus on the user’s interactions with the system to achieve a valuable outcome. Therefore, use cases work well for interactive end-user applications, including Web sites. They’re also useful for kiosks and other types of devices with which users interact.

However, use cases are less valuable for projects involving data warehouses, batch processes, hardware devices with embedded control software, and computationally intensive applications. In these sorts of systems, the deep complexity doesn’t lie in the user–system interactions. It might be worthwhile to identify use cases for such a product, but use case analysis will fall short as a technique for defining all the system’s behavior.

As an illustration, I once worked on a computational program that modeled the behavior of a multi-stage photographic system. This software used a Monte Carlo statistical simulation to perform many complex calculations and it presented the results graphically to the user. The user-system dialog needed to set up each simulation run was quite simple. The complexity resided behind the scenes, in the computational algorithms used and the reporting of results. Use cases aren’t very helpful for eliciting the requirements for these aspects of a system.

Use cases also have limitations for systems that involve complex business rules to make decisions or perform calculations. Consider an airline flight reservation system, one of the classic examples used to illustrate use cases. Use cases are a fine technique for exploring the interactions between the traveler and the reservation system to describe the intended journey and the parameters associated with it. But when it comes to calculating the fare for a specific flight itinerary, a use case discussion won’t help. Such calculations are driven by the interaction of highly complex algorithms and rules, not by how the user imagines conversing with the system.

Nor are use cases the best technique for understanding certain real-time systems that involve both hardware and software components. Think about a complex highway intersection. It includes sensors in the road to detect cars, traffic signals, buttons pedestrians can press to cross the street, pedestrian walk signals, and so forth. Use cases don’t make much sense for specifying a system of this nature. Here are some possible use cases for a highway intersection:

A driver wants to go through the intersection.

A driver wants to turn left when coming from a particular direction.

A pedestrian wants to cross one of the streets.

These are use cases in the sense that they describe a goal a user is trying to achieve with the system, but they aren’t terribly useful in terms of illuminating the necessary system functionality. Exploring the interactions between these actors (drivers and pedestrians) and the intersection-control software system just scratches the surface of what’s happening with the intersection. The use cases don’t provide nearly enough information for the analyst to define the functionality for the intersection-control software.

Use cases aren’t particularly helpful for specifying the requirements for batch processes or time-triggered functions, either. My library’s information system automatically sends me an e-mail to remind me when an item I’ve borrowed is due back soon. This e-mail is generated by a scheduled process that checks the status of borrowed items overnight (the one I received today was sent at 1:06 AM) and sends out notifications. Some analysts regard “time” to be an actor so that they can structure this system behavior into a use case. I don’t find that helpful, though. If you know the system needs to perform a time-triggered function, just write the functional requirements for that function, instead of packaging it into a contrived use case.

Event-Response Tables

A more effective technique for identifying requirements for certain types of applications, such as real-time systems, is to consider the external events the system must detect. Depending on the state of the system at the time it detects a given event, the system produces a particular response. Event-response tables are a convenient way to collect this information.

Events could be signals received from sensors (signal events), time-based triggers such as scheduled program executions (temporal events), or user actions that cause the system to respond in some way (business events). In fact, the trigger that initiates a use case is sometimes termed a business event.

The highway intersection system described earlier has to deal with various events, including these:

A sensor detects a car approaching in one of the through lanes.

A sensor detects a car approaching in a left-turn lane.

A pedestrian presses a button to request to cross a street.

One of many timers counts down to zero.

Exactly what happens in response to an external event depends on the state of the system at the time it detects the event. The system might initiate a timer to prepare to change a light from green to amber and then to red. The system might activate a Walk sign for a pedestrian (if the sign currently reads Don’t Walk), or change it to a flashing Don’t Walk (if the sign currently says Walk), or change it to a solid Don’t Walk (if it’s currently flashing). The BA needs to write the functional requirements to specify both how to detect the events and the decision logic to use when combining events with states to produce system behaviors.

Table 1 presents a fragment of what an event-response table might look like for such a system. Each expected system behavior consists of a combination of event, system state, and response. State-transition diagrams and statechart diagrams are other ways to represent this information visually, but at a higher level of abstraction. Use cases just aren’t enormously helpful in this situation.

Defining the requirements for this complex system of interacting hardware and software components demands more than use cases. Most of the system’s complexity lies not in the user interactions but under the hood. An event-response approach will go much farther toward understanding the requirements for such a system.

Jama Software has partnered with Karl Wiegers to share licensed content from his books and articles on our web site via a series of blog posts, whitepapers and webinars. Karl Wiegers is an independent consultant and not an employee of Jama. He can be reached at http://www.processimpact.com. Enjoy these free requirements management resources.