Chapter 5. The Use Case

A use case is a story that describes how an actor uses the system to obtain a specific measurable benefit. Like all stories, a use case can be a good story that clearly expresses the author's vision and is well received by the audience. Or it can be confusing, obscure the author's vision, and be rejected by its audience.

What are the properties that make a use case easy to read and comprehend? Like a good story, a use case should not have multiple plots or plot fragments. Rather, it should address a single and complete goal that supports the system vision, which we call a CompleteSingleGoal (p. 118). The actor will either succeed in reaching this goal or fail to completely reach it.

One difference between a use case and a story is that a use case has more than a single story line. There may be numerous alternative ways the actor can reach, or fail to reach, the goal. The use case must describe all the different courses of action possible as ExhaustiveAlternatives (p. 129).

How should we present all these different story lines in a use case? Should we exhaustively write every possible alternative as its own story? Or should we try to write the use case story like a computer program with nested ifs, loops, and other complex logic? Neither approach is satisfactory because people find the exhaustive scenarios redundant, and most readers prefer not reading anything that looks like program logic. The favored approach is to structure all the different alternatives as ScenarioPlusFragments (p. 125), where we write the expected path for achieving the CompleteSingleGoal as a simple single story line called the scenario, and then write each alternative as an incremental addition to that story, the so-called fragments.

All good stories should have a catchy title, and a use case is no different. The title should be a VerbPhraseName (p. 122), that reminds the readers of the use case's goal.

Good stories do not distract their readers with background information or references. Rather, they include these details as supplements, such as the list of references or an appendix. The same is true of use cases: we should not distract the reader with technological details, business rules, and constraints. Rather, we can use supplemental specifications, Adornments (p. 133), to adorn the use case.

Finally, all good stories must be readable. A use case is supposed to be a work of nonfiction and serves as the basis for comprehending a system. Therefore, it is important that it be PreciseAndReadable (p. 138).

You:

Solitary country road

CompleteSingleGoal

You are working on the EverUnfoldingStory (p. 102), focusing on a ClearCastOfCharacters (p. 90).

Improper goals will leave the writers uncertain about where one use case ends and another begins.

One of the most painful events in American history was the Vietnam War, in which tens of thousands of young lives were lost, and many more tens of thousands of lives ruined. The Vietnam War made a powerful and proud nation look inward and doubt itself. Many armchair generals theorize about why the United States failed to succeed in Vietnam, but a consensus always seems to form around a lack of a clear moral purpose.

The United States had never declared war on Vietnam; its involvement started with sending advisors to assist the South Vietnamese. Slowly the United States was drawn into the quagmire that had previously swallowed France. Battles were fought; some were won, and others were lost. But it always seemed that the effort was fragmentary, with no goal.

Use cases that fail to address any goals are tangential and don't add value to the system. Those that fail to completely address one goal are insufficient, and leave the developers no choice but to look for other use cases, or guess at some parts of the system. Those that address too many goals tend to be too complex.

To build the correct system, we need to understand how an actor achieves some accomplishment of value. A story is organized into chapters. In each chapter, we want to show the hero or heroine overcoming some obstacles and achieving some particular accomplishment related to the overall story. In the same way, each use case should describe one significant accomplishment of interest to the primary actor.

We want to control complexity by partitioning our use cases into pieces that make sense to the stakeholders. A use case should describe a manageable unit of work. It should be a self-contained, logically cohesive unit that describes or references all relevant facets of a particular behavior. At the same time, it should be small enough so the reader can grasp its meaning, and not be overwhelmed by size or detail. We must consider several factors for controlling the complexity of our use cases, dealing with time and size.

  • The duration of the actor goals may vary. An actor can have some goals on the minute-by-minute level, some on the one-sitting level, and some that take multiple days to accomplish. Use case developers often miss this observation. Many people tend to focus on goals that an actor can complete rather quickly in a short session; such an approach can result in small, fragmented use cases. Worse, they can completely overlook services that are important to the actor.

  • Excessively large use cases can bury the stakeholder in an avalanche of details and obscure the purpose of the use case. The longer a use case, the longer it takes to write, and the harder it is for the reader to keep all the details straight. Use cases resembling Russian novels are bad because they are too complex, contain too much information, and provide too many alternatives. The readers and even the writers can lose sight of the use case goal, implement the wrong service, and emphasize the wrong characteristics of the system, resulting in additional features of no value to anyone. Once again, the purpose of the use case set is to convey how the system brings value, rather than exhaustively describing everything.

  • Large use cases can inhibit reuse. Both size and detail make it hard to reuse basic features. Larger use cases can hide important system properties, making it hard to identify reusable services. Larger use cases tend to contain implementation details because writers have a tendency to substitute details for completeness. Such an approach is likely to offer solutions rather than address stakeholder needs. The result is rigid, narrowly defined transactions that are too precise to reuse in other contexts. It is simply easier to reuse smaller pieces than larger ones.

  • Excessively small use cases will describe only a fragment of some accomplishment of value. If writing use cases like Russian romantic novels is not appropriate, then what about writing them as partial stories? Unfortunately, this type of use case will cover only a portion of the overall behavior of the system, so the reader will not see its overall purpose. This style of writing results in cliffhanger endings, which are wrong because each use case needs to represent a “complete usage of value” to the actor.

  • The narrow knowledge of subject matter experts may push us toward small use cases. Experts often have a narrow focus, so they tend to propose those use case transactions with which they are familiar. Many experts favor smaller transactions because they are well versed in some particular process, but don't necessarily understand the purpose or goal behind that process. Yet these transactions only partially satisfy the actor's need, and often require one or more additional transactions to satisfy the goal of the actor.

Therefore:

Write each use case to address one complete and well-defined goal. That goal may be at any level in the EverUnfoldingStory (p. 102).

Select and name the primary actor goal with a VerbPhraseName (p. 122) that you wish to highlight. This goal may require a few seconds, days, weeks, or months to accomplish, and can be at any level. If you cannot come up with a good VerbPhraseName, then you may not have a goal after all. Good characteristics of a goal are:

  • It is associated with a well-defined actor.

  • It is valuable to the actor or the stakeholder on whose behalf the actor is working.

  • It is consistent with other goals that you have identified for the system at this level. If the goal is not appropriate for the level of abstraction that you are working at, consider reorganizing the use case model as an EverUnfoldingStory.

Be PreciseAndReadable (p. 138). Describe the different ways the primary actor can either reach or fail to reach this goal. To accomplish this, structure the use case as a ScenarioPlusFragments (p. 125), with a main success scenario describing the nominal case. This is followed by a set of fragments describing all reasonable alternatives that can affect the actor as he or she attempts to achieve the goal.

A use case should leave the system in a well-known state when it ends: either the primary actor fully obtains the goal, or the system state is the same as if the use case never happened. Use cases should not contain cliffhanger endings. The initiating and terminating events should be clear and unambiguous to the actors.

Occasionally, your use case may need to address more than one goal. This can be done without violating the spirit of CompleteSingleGoal, as long as the use case is cohesive and achieves a unified purpose. It is much better, however, to write the use case to address a higher level goal that encompasses subgoals, as well as any other issue associated with the higher level goal.

Examples

Wings Over the World

Our consultant has reviewed the Change Seat use case that Ahmed had written. Its goal was to change a traveler's seat, either as a normal exchange or an upgrade.

We can immediately see that this use case really addresses two goals: obtain a different seat or upgrade a seat. Ahmed may have correctly argued that a seat upgrade is just the same as a seat change from a system point of view, but we want to write use cases from the actor's perspective. For most air travelers, an upgrade is a very different goal from a seat change.

Combining these two goals will likely lead to long, complex alternatives that can obscure the differences between them. You can capture any steps that are truly common to both in lower-level included use cases to avoid redundancy (see CommonSubBehavior [p. 176]).

Select Exit Row Seat is another example of a poor use case goal. It says:

Select a seat in a designated exit row for the traveler.

The qualification in this example should make us question whether this statement represents a complete goal or just a fragment of another. Most airlines will not assign a seat in a designated exit row until the passenger checks in and airline staff can confirm that the passenger is physically capable of opening the exit door in an emergency. Most likely, this use case should be an alternative to Change Seat.

A frequent cause for writing fragmented use cases is that many writers tie each of their system-level use cases to specific interface details, with one use case per user-interface form. This practice frequently results in numerous system-focused use cases, such as Capture Traveler's Desired Itinerary, Present Itinerary to Traveler, Capture Traveler's Preference, Capture Traveler's Personal Information, and Capture Traveler's Payment Option. Do these examples truly reflect a useful goal for a traveler, or are they all just fragments of the goal Book Flight? The use case is inappropriate for capturing user-interface details. Such information should supplement a use case as an Adornment (p. 133).

Writing use cases around goal fragments leads to the creation of numerous closely related use cases without any structure tying them together. In this example, if you were reviewing twenty or more use cases, would it be obvious to you that Change Seat and Select Exit Row Seat are closely related? Probably not. You would lose an opportunity to simplify the system and make it more comprehensible by consolidating closely related behavior.

Wings Over the World

Sign for frog company, Rayne, Louisiana

VerbPhraseName

You have identified a use case associated with a CompleteSingleGoal (p. 118).

Meaningless, generic names will not set reader expectations or provide a convenient reference point.

Names convey meaning. A picture may be worth a thousand words, but descriptive names can say much, much more. Just the name “The Grand Canyon” instantly evokes vivid images of colors, plateaus, rock formations, mules, and snow-covered vistas accompanied by the gentle strains of the “Grand Canyon Suite.”

Businesses recognize the value of a good name, and they will spend millions of dollars researching good ones. They want something “snazzy” that instantly catches people's attention and draws customers to their product. They also want to avoid names with negative connotations that hurt their product's image. A popular business school example of a bad product name was General Motors' attempt to introduce the Chevrolet Nova into Spanish-speaking countries. Unfortunately, Nova sounds like the Spanish for “no-go.”

Using descriptive verb phrase names for your use cases is a good practice, because they accurately reveal the intention of each use case.

The name sets the tone and association for the audience and can provide a focal point for the writer. A name should reveal the use case's intention and reflect the CompleteSingleGoal that the actor is trying to achieve. A meaningful name that adequately describes a use case's purpose can give the reader more insight into a use case than several paragraphs of text. The name should offer a preview of things to come, and be descriptive enough to stand by itself, allowing the reader to work at the use case set level without having to delve into the contents of the use cases composing the set.

A descriptive, goal-based name can also help the writers understand the essence of the use cases that they are writing, and it can constantly remind them of the goals that they are trying to accomplish.

An appropriate name provides a handle for the use case. One of the benefits of software patterns is that the names of the various patterns convey sufficient meaning to become part of the development nomenclature. For example, developers can use the terms “Visitor,” “Bridge,” or “State” to describe fairly complex components to their audience with very few words. In the same way, a meaningful name can adequately describe a use case so that the audience doesn't need to read the full use case to use it.

Appropriate use case names allow you to see the big picture and work on the whole set. People working with a system at the 50,000-foot level don't care about the low-level details of the individual use cases. In fact, such details would hinder their efforts because they would quickly obscure the abstract concepts they are trying to understand or explain. Meaningful use case names assist those working at a high level by revealing the intent of the various use cases to the audience. People don't have to stop and read each one; they can instead focus on the system as a whole, without distraction.

Therefore:

Name the use case with an active verb phrase that represents the goal of the primary actor.

Begin each name with an active verb that describes the use case's goal, and follow this verb with a phrase describing its object. Be terse, yet descriptive enough to capture the use case's essence. For example, a good name for a use case describing paying an accident claim is Pay Claimant.

Choosing a good name for a use case is important, because it conveys the use case's purpose to the audience. Descriptive names are easy to work with and can significantly improve the cohesiveness of your use cases. If you have trouble coming up with a name, then you should reconsider your use case.

Examples

Insurance Claims

Use Case Naming Horrors

Consider the following names for some insurance use cases:

  • Main Use Case

  • Claim Process

  • Use Case 2

  • Process Stuff

It's nice to know that Main Use Case is apparently the important one, but what does it do? This kind of name is okay for those who already know what the system does, but it doesn't help anyone who is unfamiliar with the system. Names like this are not evocative of the use case goal; they force the audience to read most of the use cases to determine which ones interest them.

Claim Process appears to be a better name, but what does it imply? This use case name doesn't define how the system handles all claims or how users enter claims, nor does it tell what kind of claim the use case defines. It forces the reader not only to read the use case to determine its purpose, but also to look through the whole set to find the ones about the claims in which they are interested.

Use Case 2. Believe it or not, some of us have seen use cases named Use Case 1, Use Case 2, and so on before. Of course, no one had any idea what they covered, but at least we knew that there were at least two of them.

Process Stuff. Someone actually used this one too. This could be about anything, but at least it can be used in almost any context.

Good Use Case Names

  • File Accident Claim

  • Approve Property Damage Claim

  • Report Fraudulent Claim to Police

Each of these names is descriptive and conveys some meaning to the audience, so that they don't have to read every use case in the collection to understand each one. The names also serve as a convenient reference, so that the readers can easily locate only the ones in which they are interested.

You can number use cases for organizational purposes. For example:

Use Case 42: Approve Property Damage Claim

allows us to use descriptive names and organize our use cases numerically. Very short comments are also acceptable. If the use case you are describing drives the rest, then you could describe it as:

Use Case 1: Book Airline Reservation (Main)

We still refer to it as Book Airline Reservation, but we also know that it is the first use case in our collection, and it is the main one as well.

Good Use Case Names

Newspaper clippings from the Electric Institute of Washington

ScenarioPlusFragments

You are writing a use case description for the primary actor's CompleteSingleGoal (p. 118).

Readers must be able to follow the path easily through the specific scenario or story that they are interested in; otherwise, they are likely to become frustrated or miss important information.

A delightful style of children's book is the “choose your own adventure” story. These books draw the reader into the story by asking him or her to choose the hero's course of action. Do you heed the warning of the old gypsy and avoid the dark path into the forest, or do you venture into the forest to seek the legendary magic amulet? The reader must choose one alternative. If you heed the gypsy warning, then the reader turns to page 59 to continue the thread of the story. If you choose to venture boldly into the forest, then the reader turns to page 112. One choice advances the hero closer to his goal, while the other may lead to failure and death.

A “choose your own adventure” story is a good style for writing use cases, because it makes it easy for the readers to follow the various paths in a use case.

An interesting use case needs to capture alternatives to the main success scenario. Many different things can happen as an actor attempts to attain a goal. Things don't always go right. Sometimes, if the system is prepared, it can detect the problem and take the steps necessary to rectify it. Other times, however, things can be screwed up too much to continue, and the best course of action is to stop. The system should be able to handle these situations gracefully. To do so, the developers need to know all the things that they can reasonably expect to go wrong before they build the system.

The difference between a use case and a “choose your own adventure” story is that the adventure story has no “main” success story line, so the reader must make the choices at various moments while reading the book. Unlike the story, a use case is a description that should reveal the crisscrossing structure, not hide it. There are several ways we can show this structure:

  • Writing every alternative as a complete story will obscure the differences between story variations. We could write every possible variant of the plot as an entire story. This has the advantage that the reader can simply read any complete variation of the story from top to bottom. However, there will be a great many of these to read, and at some point the reader will have trouble telling the difference between, say, plot variant 17 and plot variant 18. The two variants might be almost entirely similar, perhaps differing in only two sentences. At that moment, the structure becomes a drawback, since the reader will get more, not less, confused over time.

  • Separating out every variant also makes the writer's life difficult. Any change in the story line usually affects a number of the variants, and the writer must find and change every variant, trying to be consistent and accurate in the change. This is both tiring and error-prone, so we want to keep the number of variants to a minimum.

  • A large number of if statements will clutter the story. A second alternative is to put if statements into the story, which shortens the writing. Programming languages are constructed this way, and many people have been trained to write in the form, “If such and such is the case, then so and so happens.”

    If our story had only one of these ifs, then this would indeed be a practical way to proceed. However, most of the stories that get written into use cases have a large number of variations, from a half dozen up to several dozen, sometimes with if inside ifs. This structure quickly gets out of hand, and the reader is soon unable to follow the story lines. It is important that every reader, from end user to executive to programmer, be able to understand the crisscrossing story, and so the “if . . . then. . . , but if . . . then . . .” story line structure is no longer recommended.

  • People cope well with incremental complexity. There is a surprising third alternative that has shown itself to be effective. People seem to be quite adept at modifying and adding complexity to a base concept a little at a time. We often see people describing a simple concept, and then saying, “Well, actually, it isn't that simple. This can also happen. . . ,” adding a twist to the story. The listeners to these explanations are able to build up a complex understanding, a small piece at a time. We can use this idea to convey the intertwining story line (Cockburn 2001, p. 87).

The main success scenario needs to be clearly identified. If all threads are written as scenarios, then which scenario is the most important one? The readers and the builders need to know which scenario is the main success scenario that you expect the primary actor typically to seek.

Therefore:

Write the success story line as a simple scenario without any consideration for possible failures. Below it, place story fragments that show what alternatives may occur.

The main success scenario describes how the primary actor accomplishes the goal in a straightforward manner. It doesn't have to be the shortest possible path or the only possible successful path, but it should be the normal desired path for reaching the goal, that is, the one the users are most likely to follow.

For each of the Exhaustive Alternatives (p. 129) that has to be considered, create a header after the main success scenario. First, describe the DetectableCondition (p. 148) that cause the actor to take the branch. Then describe what happens in this branch, and how it ends: either rejoining the main story or ending in failure.

Each scenario in a use case should have a clear purpose. Write each scenario in the use case as a set of LeveledSteps (p. 153), each showing the ActorIntentAccomplished (p. 158), making ForwardProgress (p. 162) toward the use case's CompleteSingleGoal.

Usually, the fragment ends in a fairly obvious way, by retrying the step that preceded the branch, fixing up the step so that it can rejoin the next step in the main success scenario, or simply failing altogether. On occasion, it is necessary to name explicitly where the story picks up again.

Occasionally, some of the fragments become long and complex enough to obscure the rest of the use case. To make the use case PreciseAndReadable (p. 138), at this point it would be useful to create a PromotedAlternative (p. 190). Extract the alternative and put it into a separate use case.

You will occasionally want to associate other information with the use case: performance information, business rules, or possible screen designs. Create places for such information as Adornments (p. 133) to the use case in the template.

Note: In terms of BreadthBeforeDepth (p. 48), this pattern identifies these stopping points:

  • Main success scenario

  • Naming the conditions

  • Finishing some of the fragments

Examples

Auto Insurance Claim Handling

Use Case 5.1 illustrates a main scenario with several alternative fragments overriding some of its steps. While this example is fairly straightforward, we can often identify many viable alternatives for a scenario.

Level:

Railroad roundhouse turntable

ExhaustiveAlternatives

You are writing a use case as a ScenarioPlusFragments (p. 125).

A use case may have many alternatives. Missing some alternatives means the developers will misunderstand the system's behavior, and the system will be deficient.

We had just moved, and this was our first winter in our new home. For two days it snowed, dumping nearly three feet of heavy, wet snow. Even with chains, there was no way my car would get out of the driveway, and I was forced to begin shoveling. After an hour I had managed to clear my driveway, feeling quite satisfied with my accomplishment. That is, until I saw the municipal snowplow barreling down the street, pushing a wall of snow in front of it, directly into my freshly shoveled driveway. Swearing mightily, I cleared the snow away, and then I noticed the wall of snow that the plow had pushed into my neighbor's driveway. He was an older gentleman, and I thought it would be neighborly to clear the snow out of his driveway.

Halfway through clearing his driveway, I heard the rumble of machinery down the block. I thought, “Oh no, not again. The plow's coming back to finish me off.” Then I saw that the city was using a small front-end loader to clear away the snow that the plow had pushed into people's driveways! I didn't know whether to laugh or cry, because I could have just waited, warm and cozy, in my house for this plow to come by.

Later, when I told my neighbor, he laughed and apologized profusely. “I'm sorry. I forgot to tell you that the city clears the driveways after the plow comes through.” I had gone out and gotten cold and soaking wet because I did not know that the alternative of just sitting and waiting was available to me.

A good use case describes all important alternatives, so that the developers can properly address potential problems, protecting the users from unpleasant surprises.

Developers need to know how to handle errors. Error handling and exception processing constitute the bulk of most software-based systems. Certain classes of errors are well known and easy to handle, but a significant number of errors are hard to predict and difficult to detect. For example, it is easy to detect missing data, but not so easy to find problems with boundary conditions or subtle interactions between seemingly unconnected fields. It is difficult for a system's developers to identify potential errors because they are working under time constraints, and good error finding requires “out-of-the-box” thinking. Developers focus on using the system correctly, and they often fail to consider cases of incorrect system use because these actions break the rules. But users do not share this constraint and often, through unfamiliarity, necessity, or experimentation, attempt to use the system in ways the developers never considered. A robust system must be able to handle these types of situations without failing. But the only way to handle these errors is to identify them before building the system, so that the system knows how to recognize and handle them. One of the most important facets of the analysis process is identifying potential error situations that the system is likely to encounter, and then developing uniform policies for handling them.

Schedule pressure limits the time developers can spend identifying variations. Identifying variations requires time, creativity, and out-of-the-box thinking. It can be mentally tiring to think about many of them and keep them straight. Developers often fail to see the value in this exercise, especially when many of the differences are so minuscule that they appear to be meaningless, and when there is intense schedule pressure. But this kind of thinking is backwards, because this information is absolutely essential for estimating the scope of a project. Variations represent a significant, and possibly a majority, portion of the effort involved. Acknowledging them helps to determine an accurate schedule for the project.

Some of the variation-handling policies need significant investigation. Identifying errors is often the easy part. Handling these errors can be much more difficult and often requires significant time and effort. It is easy to decide that certain input fields should allow only integers, but it requires a coordinated policy and potentially complex components to implement this feature efficiently for tens or hundreds of similar fields. Moreover, other input fields may have somewhat similar constraints, and it is highly desirable to use the same mechanism to handle these fields as well. But designing this kind of feature requires real work.

Having information about the variations helps developers build a robust design. The better the developers understand a system, the easier it is for them to design and build it. Even when using iterative development processes, it is often much cheaper and simpler to build a system when its developers are aware of error conditions at the beginning of the development process. Having this knowledge allows them seamlessly to incorporate exception handling into their system architecture and handle these conditions in an effective manner, providing a much more robust and user-friendly system. They can still add functionality later on, but it is hard to incorporate these add-ons seamlessly into the system's architecture. As a result, the add-ons are often not as well structured as they would have been if they were part of the original system.

Therefore:

Capture all alternatives and failures that must be handled in the use case.

Once you have identified all of your use cases and their main courses, identify as many variations from the main course as you can. Capture all of the variations that you want the system to handle, yet be selective. These variations should be DetectableConditions (p. 148) that result either from the user using the system differently or from error conditions. Eliminate all the variations that begin with conditions that the system cannot or does not have to detect, and then merge all the variations that produce the same resulting behavior.

Document the remaining variations in the use case using the ScenarioPlusFragments (p. 125) format, listing the appropriate DetectableConditions as the first step of each scenario or fragment.

Note: This is a good time, when doing BreadthBeforeDepth (p. 48), to find all the alternative conditions that will force different paths, before spending much time on the extension handling. The list of conditions will act as a table of contents of issues that need to be researched over the following days.

Working BreadthBeforeDepth is the third place at which to pause and examine your work. (The first is after you have named the actors and UserValuedTransactions (p. 95). The second is after writing the main success scenario.)

Examples

E-mail Access

Use Case 5.2 demonstrates how to itemize a use case's alternate courses. Instead of defining a separate use case for each of the alternate and error courses, we itemized each as a deviance from the original. This format nicely encompasses those situations in which the user performs several separate actions, such as saving some e-mail, forwarding some e-mail, and replying to still other e-mail.

Level:

Cadet dressing for Sunday dinner, Selma, Alabama

Adornments

You are writing the use case description as a ScenarioPlusFragments (p. 125), keeping the steps TechnologyNeutral (p. 167).

The inclusion of nonfunctional requirements in a use case can quickly clutter and obscure the use case.

Okay, I admit that I am an opera fan. (Can you guess which one of us?) I enjoy listening to people shout at each other in a foreign language while wearing strange costumes. Most people say they don't understand opera. But the stories behind the operas are often fairly simple, usually something about young romantic love thwarted by meddling parents or the patriarchy. An adequate synopsis of an opera can usually fit on two pages of a program.

Of course, there is a great deal more information available about an opera that can help you understand it. For example, what are some of the critical interpretations of the opera? Or, what were the historical influences on the composer that led to the creation of the opera? The answers to these questions are never included in the synopsis because they would clutter and obscure the synopsis. Rather, separate articles in the program answer these questions.

A use case is similar to a program synopsis because it offers an understandable explanation of a complicated production. You should be able to read a use case and understand how a system delivers value to its actor without worrying about user-interface details, data storage details, or other nonfunctional requirements.

The purpose of a use case is to express clearly the functional requirements of a system. A use case should show what a system does, not how it does it. It should provide a clear, concise description of the services that a system provides its users in plain, everyday language (Jacobson et al. 1992). A reasonably intelligent person, regardless of his or her technical background, should be able to pick up a use case and quickly understand the functionality that it describes.

We often discover nonbehavioral information while researching functional requirements. It is very common to collect all kinds of valuable information when gathering system requirements. Some portions of this collected data, such as the types of actions to perform or the number of users to support, form a basis for the resulting requirements. Other portions, including such items as sample reports, example GUIs, or generated data files, don't directly map into the requirements, but instead serve to illustrate and clarify them.

Inclusion of nonfunctional requirements in the use case is distracting. Excessive detail makes use cases harder to comprehend and forces readers to wade through more material and grapple with issues that they don't need to understand. Therefore, we don't want to include this extra information in the use case proper. The most common type of unnecessary information is user-interface details, which can quickly bloat an otherwise simple use case into an incomprehensible monster. Likewise, a detailed description of how the system captures and validates customer shipping information usually does not help your understanding of a use case describing how a customer makes a purchase.

But we do not want to lose information that aids in understanding the use case or is valuable to the developers. Just because some data describe specific details or are highly technical doesn't mean that the information isn't valuable. Many of these nonfunctional requirements offer insight into the use case and could well be information that the developers need to implement the system. Because much of this information is either specific or relevant to a use case, we need to keep it close to the use case so that the readers are aware of its existence. The information could be captured in separate documents, but then we would lose a lot of the context that comes from the close association of the nonfunctional requirements with the use case.

Therefore:

Create additional fields in the use case template that are outside the scenario text to hold the supplementary information that is useful to associate with the use case.

Nonfunctional details such as business rules, a user-interface sketch, external interface protocols, data validation rules, and even outstanding issues (so-called TBDs—To Be Determineds) can be added to the use case in a supplementary section. This helps keep the use case PreciseAndReadable (p. 138) and the steps TechnologyNeutral. Nonfunctional information does not clutter up the basic use case, but it is still associated with the relevant use case.

Examples

Wings Over the World with Adornments

Our consultant is explaining to Ahmed, the chief architect, the consequences of including the business rules in the use case. A fragment from Ahmed's Change Seat use case appears in Use Case 5.3.

Use Case 5.3 is a simplified fragment, and we should remember that airlines tend to have Byzantine rules regarding changes to tickets. We have seen simple use cases bloated by business rule descriptions into thirty-page monstrosities. Yet, the actual Change Seat use case may be as simple as the one shown in Use Case 5.4.

In this revised version of the Change Seat use case, we test to see only if the traveler is eligible for a seat change. In a separate section of the use case—or even in a separate document—we capture the eligibility rules for seat changes. There are several advantages to this approach:

  1. The reader can clearly see the flow of events because the use case description is not cluttered with the business rules.

  2. There are fewer alternatives in the use case. There may be dozens of rules regarding whether a traveler is eligible for a seat change. If we try to capture all of these rules as part of the use case, we risk specifying an entry in the alternatives section for each situation where we can fail the rule. But in this example, the net result of failing any of the rules is the same: the seat is not reassigned. So we have only one alternative, DetectableConditions (p. 148).

  3. Whenever the business rules change, we do not have to update the use case scenario.

One of the most frequent mistakes use case writers make is that they believe the use case replaces all other tools for system specification. Business rules, data formats, and user-interface navigation have no place in the use case description. But these items are important and valuable pieces of information that we want to associate with the use case. While this information should not be part of the use case description, it can be written up in supplementary documents that are anchored by the use case. Figure 5.1 conceptually shows how nonfunctional requirements revolve around the relevant use case.

The use case anchors other supplementary requirements (adapted from Cockburn 2001).

Figure 5.1. The use case anchors other supplementary requirements (adapted from Cockburn 2001).

The use case anchors other supplementary requirements (adapted from Cockburn 2001).

Engineers discussing blueprints. Wilson Dam, Alabama, Tennessee Valley Authority (TVA).

PreciseAndReadable

You are writing the text for a use case as a CompleteSingleGoal (p. 118).

Use cases that are too complicated for nontechnical readers, or too imprecise for developers, are deficient and likely to result in poorly built, inadequate systems.

Beginning guitarists quickly learn that it is difficult to determine how to play a song correctly from traditional sheet music, as it is possible to play any given note or chord at a number of different locations on a guitar. Traditional musical notation shows what notes to play, but it can't always show where or how to play them. For this reason, many guitarists prefer a specialized notation called tablature, which is very precise and easy to learn, demonstrating where and how to play a lick or riff in such a manner that a novice can try it. The lick may be very complex, and require much practice, but any player can at least see how it is done.

In a similar way, a use case should be written with an easy-to-understand precision that meets the knowledge level of most members of the use case audience.

A use case should be readable by both the stakeholders and the developers. Any use case can have several different audiences with varying needs and technical abilities. Higher level audiences, such as customers, can get turned off if the use cases are too difficult to read or too technical to follow easily. Likewise, lower level audiences such as developers will not use use cases if they contain too much “fluff” or fail to describe the system adequately. Well-written use cases address the needs of several different audiences without unduly favoring any.

Developers tend to add detail and solutions. This tendency is natural, and hard to control, as people believe extra details add clarity. Unfortunately, these details are often unnecessary, adding little value to a use case. Worse, they can complicate it, making it more difficult for the reader to understand. Problem solutions are especially unnecessary in use cases, because the people writing use cases are still trying to understand and describe system behavior. They are hardly in a position to propose meaningful designs, because they haven't fully determined the problems associated with this behavior. Well-written use cases describe the essential characteristics of a system's behavior without specifying technical details or favoring a specific implementation.

Nontechnical stakeholders are likely to miss necessary considerations. Nontechnical people have difficulty understanding highly technical documentation. Those without an understanding of the problem domain are unlikely to make the proper inferences from it, because they are unaware of all of the nuances of the problem domain. Well-written use cases specify the issues involved with a system's behavior and spell out the consequences of its various actions.

We want to encourage a dialogue between the stakeholders and the developers to ensure the accuracy of the requirements. One of the greatest benefits of use cases is that they make it easy for stakeholders, many of whom are nontechnical, to understand a system's behavior and determine if it is what they really want. If not, they can work with the system's developers to describe the system better so that it meets their needs. Unfortunately, developers often ignore this benefit because they are in a hurry to build the system. But use cases are meaningless to the system developers until they correctly describe a system that the users really want. Well-written use cases contain a consensus of people having different system views (ParticipatingAudience [p. 35]).

Dual models are unacceptable because they can become disjointed and are difficult to maintain. Having different sets of requirements documents for the customer and the developers is a project nightmare. Project teams are under too much pressure; the documents will soon become disjointed and difficult to maintain. Updating multiple copies of a document is not only unnecessary, tedious, and time-consuming, but it also becomes unworkable on most projects. Even worse, multiple versions of design documents unnecessarily introduce ambiguity. When someone refers to a use case, how do you know which one she is referring to? Are your tests based on what the developers did, or what the customers want?

Therefore:

Write the use case to be readable enough so that the stakeholders bother to read and evaluate it, and precise enough so that the developers understand what they are building.

Every use case you write should accurately and fully describe a CompleteSingleGoal, without being so verbose that the audience cannot read it or so high level that it fails to communicate enough information.

The cardinal rule for writing is “know your audience.” Determine who needs these use cases, and write each one using your audience's terminology, in a style that they can easily understand. The correct level of precision and readability presents a moving target, so it is important that you understand your audience's needs and abilities when writing each use case.

Do not substitute detail and verboseness for precision. A good general rule to use is “Never expect your audience to fill in the gaps.” Use plain language to describe essential system behavior, keeping the steps TechnologyNeutral (p. 167). Include only that information necessary to describe the system's behavior. Describe the behavior clearly and precisely enough so that an uninformed reader can fully understand its consequences, without missing important events. This precision benefits not only the customers, but also the developers, who should not have to make guesses when building the system.

Examples

Wings Over the World: Readable but Imprecise

Ralph is the Wings billing expert, and he believes that formality in writing use cases is just busywork that delays getting down to the real work of building the system. Frustrated with the formality advocated by Ahmed, he wrote his own version of the Change Seat use case, shown in Use Case 5.5.

This use case is written as a brief or high-level use case. It uses free-flowing prose to describe the exchange between the traveler and the system. In a tight-knit workgroup, this level of precision may be suitable. After all, you do not want to waste a lot of energy writing detailed specifications if you do not have to (BreadthBeforeDepth [p. 48]), QuittingTime [p. 68]). On the other hand, the Wings project is being outsourced, and this brief does not provide enough precision for a distant team to implement this feature correctly.

Wings Over the World: Precise but Unreadable

While imprecision results in ambiguity, excessive precision results in unusable use cases. Ahmed had used UML Object Constraint Language (OCL) in his use case description. OCL is a formal language for specifying object constraints and is intended for situations in which natural languages are too imprecise. He has used OCL to describe the following rules for seat change eligibility:

  • t : Traveler

  • f: Flight

  • t.seatAssignment->notEmpty and

  • t.ticketClass = #J or t.ticketClass = #Y

  • t.ticketClass is in set and f.departureTime < 24 hour

Ahmed suggests that using OCL will reduce ambiguity in the use cases. There is justification for this point of view, because Wings Over the World is outsourcing the project, and the more precise the specifications are, the less opportunity there is for misunderstanding on the part of the developers. Some software developers believe that using formal languages in specifications can greatly reduce the potential for ambiguity.

But this level of precision is too complex for most readers to follow. On the topic of formal specifications, a noted software methodologist is reported to have said, “I like writing these, but I really hate to read them!” Even though stakeholders and designers may have different interpretations of the requirements using natural language, the real problem may be that the stakeholders do not fully comprehend the formal language or, worse, are intimidated by it. Therefore, we may not know if we have the correct specification in the first place. We may in fact precisely capture the wrong specifications because no one can clearly understand the language—but few people are willing to admit they cannot understand a spec.

A good specification is one that the stakeholders can read and then clearly tell you, “No, this is completely wrong. You do not understand my operation. Let me tell you how things really work here . . .” Although your description was incorrect, it was clear enough for the stakeholder to comprehend and tell you that it was wrong. On the other hand, if the stakeholder reads the spec and then tells you hesitantly, “Well, OK. I guess so. You're the expert in this stuff after all,” then you are heading for trouble. The stakeholder might not understand the specification and may be withdrawing, leaving you holding the bag.

Higher levels of formality in specifications can often give the developers a false sense of security that there is less opportunity for problems resulting from ambiguity. Nothing can replace a good ongoing dialogue with the stakeholders.

Trade-offs and Collaborations

As its name would suggest, the use case is the key component of use case modeling. Its purpose is to illustrate how a system enables an actor to meet a particular goal by showing all of the appropriate paths that the actor might take, as well as those situations that could cause the actor to fail. The use case is primarily organizational in nature, providing order and structure so that the reader can easily identify and follow the different paths, or scenarios, as the actor progresses toward his goal.

UserValuedTransactions (p. 95) tells us to capture the smallest set of goals that delivers all necessary services to the actors. A well-written use case presents a story describing how the system helps the primary actor completely reach a particular goal, a CompleteSingleGoal (p. 118). The most important factor to consider in this regard is granularity. A use case that addresses multiple goals becomes awkward, confusing to read, and hard to develop from. A use case that addresses a partial goal will likely force readers to wade through multiple use cases to follow a single thread of thought, making it easier for them to miss important actions.

There are several factors to consider when writing CompleteSingleGoal, and we have identified several patterns to help. A well-written use case contains a main success scenario and an orderly, well-structured collection of fragments. We call this style ScenarioPlusFragments (p. 125). The scenario describes a singular and complete sequence of events that the actor follows while attempting to achieve some goal; it results in either success or failure. The fragments are a list of ExhaustiveAlternatives (p. 129) that describe any and all plausible alternative situations that the system can reasonably expect to encounter when attempting to meet this goal. This list is important because it enumerates the situations that the developers need to handle, and helps them to quantify the effort that will be involved.

Aim to keep these various pieces simple and free of clutter. If you have some information that doesn't really belong in the use case but you feel is still valuable, then you append it to the use case as an Adornment (p. 133).

A meaningful use case name is also important. Every use case should have a VerbPhraseName (p. 122) that gives the reader a hint of the use case's contents and provides a word association, similar to a pattern name, that the audience can use to describe the use case's purpose in the course of subsequent conversations. The name is tightly coupled to the CompleteSingleGoal. If the goal changes, you should consider changing the name as well, or if you want to keep the name, you need to verify that the goal is correct. If you have trouble coming up with a name, then you should question whether your use case really represents a CompleteSingleGoal.

Finally, a use case should be PreciseAndReadable (p. 138), written so that it is tailored to its audience. Every use case should accurately and completely describe some behavior, but at the same time it should not contain so much detail, nor be so verbose, that the audience cannot read it. The correct level of precision and readability presents a moving target, so it is important that you know your audience when writing each use case.

These guidelines are important because they describe a structure for organizing the details associated with multiple complex scenarios. Use cases without this structure can be very cumbersome, forcing readers to jump between seemingly unrelated sections of text or to read volumes of tediously repetitive sections that seem to differ little from each other. CompleteSingleGoal and ScenarioPlusFragments are important factors in writing quality use cases. The organization of the individual scenarios is just as important, and is the topic of the next chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.93.132