Chapter 6. Scenarios and Steps

The scenario and step patterns capture the signs of quality for writing good stories about systems. A sign of a quality story is that it stays focused, steadily advances toward its climax, and does not distract the reader with arbitrary or optional plot twists. It does not bore its readers with long, descriptive narratives that don't add any value to the plot.

Like any good story, it must always be clear in each use case step who is speaking and acting. ActorIntentAccomplished (p. 158) recommends that each step clearly describe what is accomplished and who is responsible for accomplishing it. Furthermore, it's not enough just to know who is speaking or acting, but each step in a use case scenario must make ForwardProgress (p. 162) toward the primary actor's goal. Steps that don't advance toward the goal are meaningless, and don't belong in the use case; they can only distract the readers.

Wishes, fantasy, and magic are all part of good fiction, but they are certainly not part of good use cases. A system must operate in the real world. DetectableConditions (p. 148) recommends that each scenario be something that can actually happen or be detected by your system, as opposed to listing all conceivable alternatives.

While technology is part of the real world, technology or implementation dependencies are not part of a good use case. Each step and scenario should be TechnologyNeutral (p. 167). Issues such as technology constraints or recommendations, user-interface requirements, and business rules are supplemental as Adornments (p. 133) and not part of the use case proper.

Finally, we should never ask a reader to cope with a mixture of complex and trivial steps written at different levels of abstraction. Good use case descriptions consist of scenarios with LeveledSteps (p. 153), where each step is similar in scope.

You:

The U.S. Weather Bureau station at the National Airport, Washington, D.C.

DetectableConditions

You are structuring the ExhaustiveAlternatives (p. 129) for a use case that can happen under differing conditions.

Writers always wrestle with how many and which conditions to include.

Playing the stock market became very popular during the dot-com bubble of the late 1990s. Every investor had the same dream: timing it so that they bought stock at its absolute lowest price, and selling it at its peak, becoming enormously wealthy in the process. Many investors developed complicated methods for determining just where the market was in its cycle, but all of these techniques shared a flaw: It is absolutely impossible to detect if the market has either peaked or bottomed out until well after the fact, when it is too late to act.

A system cannot handle events that it cannot detect. If the system cannot detect an event, then it cannot take the appropriate steps to deal with it. Any code that is written to handle an undetectable event is wasted, because the system will never know to run it. It is possible that this condition may be a form of another detectable condition, but treating it separately can lead to repetition. For example, if you are writing a use case for a computer to operate a car, losing a key, having a bad starter, or finding no gas in the tank all lead to the same condition: the car will not start. Although the resolution of each situation is different, the onboard computer doesn't care, it just knows that the car won't start.

The developers need to know what conditions to detect. Effective use cases provide the stakeholders and developers with a complete picture of a system's behavior, enumerating all of the conditions that they can reasonably expect the system to encounter, and a brief description of their resolution. Otherwise, the readers may not realize that a particular event can happen, or if they do, they are left to guess at its resolution or to track it down themselves. We want to capture every reasonable possibility, so that the system developers know what business rules they need to incorporate.

Fear of overlooking an important alternative encourages developers to specify irrelevant conditions that cannot be detected by the system. If the people writing the use cases miss a condition, either the developers or the end users of the system will likely bump into those conditions later. Researching detailed business rules late in development is expensive. Discovering a forgotten condition after the system has been put into service is even more expensive. This reality, plus a natural tendency to feel that a thicker requirements document is better, tends to lead beginning use case writers to enumerate every circumstance imaginable as alternatives that the system should handle.

Many apparently different conditions can lead to writing unnecessary alternatives. Writing, reading, and reviewing a use case document is an expensive and tiring business. You don't want to write more than you have to, and it makes no sense to write scenarios that cannot happen. Also, if you write the same condition in several ways, the developers may implement what should be one handling procedure several different ways. Both situations can lead to code bloat.

Therefore:

Include only detectable conditions. Merge conditions that have the same net effect on the system.

Each scenario in a use case must begin with an action that the system is able to detect. Otherwise, the system will never be able to execute the scenario, and you are only wasting valuable time writing it, and you risk introducing features that unnecessarily complicate the system. Being unable to come up with a detectable condition to initiate a scenario may indicate that the scenario doesn't belong in the use case.

If you find a scenario that begins with a nondetectable condition, ask, “What general condition is this scenario trying to handle?” If you can identify the condition, then use it to initiate the scenario; otherwise, eliminate the scenario, because it can't happen. Be careful, however, because a nondetectable condition quite often is a special case of a more general detectable condition, and several apparently different conditions may mask the same basic set of actions. While a use case should capture all of the conditions that the system must be able to handle while resolving a specific goal (ExhaustiveAlternatives), it should capture only those, without duplication.

Examples

The ATM JAD Session

Many things can go wrong when a customer accesses an automated banking machine. Let's eavesdrop on a group of ATM developers brainstorming alternatives in a Joint Application Development (JAD) session:

“What are the situations that can get in your way while getting money from an ATM?”

“Once, when I bent down to tie my shoelaces, before I straightened up again, the machine had both pushed out the money and sucked it back in again!”

“I was picking up my crying baby, and the same thing happened!”

“It ran out of ink on me, and I couldn't read the receipt!”

“I accidentally put in my library card!”

“There was some gum stuck in the card reader!”

“I got all the way there and forgot my card!”

“I got there and the power was out!”

“I was in the middle of using it and the power went out!”

The note taker at the board says, “Right. So I'll set up different scenarios in this use case: One for bending down and tying shoelaces, and one for attending to babies.”

At that, someone quickly pipes up, “Wait a minute. The machine can't tell why they didn't take the money. All it can tell is that that they did not take the money within a certain time period.”

This speaker is right. It makes no sense to write down a condition that the system can't detect. In such cases, all the system can detect is that time went by and the money did not get taken.

“What's the difference between sliding a card in upside-down and sliding one in that is badly scratched?”

“None. Put them together: Card unreadable.”

While you are at it, remove any conditions that the system does not actually have to handle. Each unnecessary condition that gets written into the requirements document increases the cost of the final system. Those that really must be detected must be written down, of course. But sometimes people get so creative and detailed that they include things that really don't need to be included.

“Hey! What about when the ink runs out?”

“It's expensive to build a low-ink detector. How about we just have someone check the machine once a day to see that the receipt is still printing well enough to be read, and otherwise wait for someone to complain?”

“Hey, what about when the printer accidentally pushes the receipt crooked and it bends back up into the machine and the person can't get it?”

“They don't need it.”

Finishing off this ATM example, suppose that the main success scenario is written as shown in Use Case 6.1.

Notice how each alternative describes a distinct action that the ATM can reasonably be expected to detect. Because each step distinctly addresses a real condition, none are duplicates.

Wings Over the World

In Chapter 5, we considered the problems caused when Ahmed placed the business rules in the use case. His Change Seat use case was apparently thirty pages long because he had incorporated the business rules for checking for eligibility. He had then written alternatives for the failure of each business rule. But from the point of view of the traveler, she was either able or unable to change her seat. She doesn't care why.

Now Sitra has run into the same problem. She has incorporated technology details into her Reserve Flight Segment use case. For each of the different RAPIER failure codes, she thought she would have to create an alternative in the use case. This approach would lead to the creation of a large number of alternatives. However, it turns out that there are really only three outcomes: either (1) RAPIER was able to reserve a seat, (2) it failed because there were no seats available, or (3) it failed because there was a system failure.

Wings Over the World

Poe Lock, Sault Ste. Marie, Michigan

LeveledSteps

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

Excessively large or excessively small use case steps obscure the goal and make the use case difficult to read and comprehend.

Anything can be described in smaller and smaller steps, until it loses its sense. Consider the following alternative descriptions of something as simple as stepping up to the sidewalk:

  1. She steps to the sidewalk.

  2. She lifts her foot from the street to the curb.

  3. She lifts her foot, arcs it through the air, and lowers it to the pavement.

    1. She rocks her foot.

    2. Disengages her weight and frees the foot to be lifted.

    3. Lifts it in a curve higher than need be.

    4. Shifts her weight slightly forward.

    5. Brings the foot heel first down onto the curb.

    6. Adjusts to support her weight as it moves above.

    7. Then stands on it.

Excessively small steps make a use case long and hard to read, and they obscure the “why.”The “stepping onto the sidewalk” example demonstrates how excessively small steps make the reading long and tedious. Worse, it hides the intent in the details.

Excessively large steps may bury important behavior. The opposite occasionally happens; the writer operates at a very high level of abstraction and makes large leaps in the narrative, omitting key actions the developers must know about.

Mixing levels of detail in a scenario is distracting. Occasionally, one must write adjacent steps at different levels of abstraction. Too much of this distracts the reader from what is supposed to be happening and makes correct interpretation of the instructions difficult.

Therefore:

Keep scenarios to three to nine steps. Ideally, the steps are all at similar levels, and at a level of abstraction just below the use case goal.

Write each step to show ActorIntentAccomplished (p. 158) with the actor making distinct ForwardProgress (p. 162) toward the goal. Keep each step TechnologyNeutral (p. 167). Make the goal of the step at a level of abstraction lower than the CompleteSingleGoal (p. 118). The steps themselves are generally kept at similar levels. If you need to explain how a step is performed, then create a smaller use case that explains the details underlying the step using the EverUnfoldingStory (p. 102) to expand from a short description to a fuller description. The step's goal becomes the CompleteSingleGoal for a lower level use case.

Examples

A Long and Tedious Use Case for an On-line Store

All of the steps in Use Case 6.2 are legitimate, but the levels are too low. The result will be a very long and tedious document.

The usual motivation on the part of the use case writer for creating long and tedious scenarios like this example is to specify all the fields of personal information the system should collect from the user: surname, first name, middle initial, and so on. Use cases are not interface specifications nor are they data dictionaries, although many use case writers unfortunately tend to write them that way. Such information should be expressed as Adornments (p. 133) to the use case. We can level this long and tedious scenario by simply consolidating the data capture steps, as in Use Case 6.3.

If the reader wants to know what data the system collects as personal information, then she can look up the definition for personal information in the data dictionary.

In general, we find that good writers keep a single scenario to less than ten steps. It seems that this is the number that readers can follow and understand easily.

A Use Case with Excessively Large Steps for an On-line Store

What if the steps are excessively large? Consider Use Case 6.4.

This example meets our less-than-ten-steps rule, but it really doesn't tell us any more about the system than we could deduce from the name.

We can expand these excessively large, or “overloaded,” steps by asking, “How is that accomplished?” Breaking the two steps into smaller steps, we now notice that the system was supposed to perform some intermediate actions, as shown in Use Case 6.5.

A Use Case That Mixes Large and Small Steps for an On-line Store

What if we mix large and small steps? Consider Use Case 6.6.

While this scenario has less than ten steps, there is a vast gulf between the levels of the first steps and the sixth step. It would be better if the first five steps were merged into two or three.

We'll merge the first four or five steps by asking “Why were the user and system doing those things? What were they trying to accomplish?” The answer is that the user wanted to log in. So we can revise the steps as shown in Use Case 6.7.

Level:

Company dance given in Moose Hall, Lancaster, Pennsylvania

ActorIntentAccomplished

You are writing the steps of a scenario as LeveledSteps (p. 153).

Both readers and developers get confused about a system's behavior if it is not clear which actor has responsibility for performing a step, and what the actor is trying to accomplish in that step.

Some time ago I was visiting friends who have young children. Their seven-year-old son was trying to tell me about a movie that he had just seen.

It was so cool. These guys search for this monster that is sinking ships, and, well, they find it, only it's a submarine. They get captured and travel underwater in the submarine. There is this guy and he's really fascinated by the submarine and the submarine captain is this ex-prisoner guy and he's got an attitude and he's always mixing it up with this other guy. And then there is this giant squid that nearly eats him, but the other guy harpoons the squid and saves him.

If I had never seen Disney's version of Jules Verne's 20,000 Leagues under the Sea, I would have had a lot of trouble following this synopsis. I would have been confused as to which “guy” was fascinated by the submarine, who had the attitude, and who saved whom when the Nautilus was attacked by the giant squid.

Writing quality use cases is hard work. It takes a lot of mental energy to create good prose. Often, people have trouble writing PreciseAndReadable (p. 138) use cases. Nonprogrammers tend to write ambiguous steps and miss the meaningful details the developers need to know. Programmers, on the other hand, tend to generously incorporate both design and technology details in their use cases, making them too hard for the nonprogrammers to understand. Often, programmers are told to write the use cases that they themselves will implement, leading them to write entirely from the system's perspective, leaving out what the other actors will do.

The developers need to know clearly what they are to implement, at what moments the system should wait for input, and when the system should take the initiative. Otherwise, they are left to make their own assumptions about these issues, or spend time tracking down details they should already have. The cost of miscommunication is high, so we aim to write use cases that are general enough for all of the stakeholders to follow, yet precise enough for the developers to use when building the system (PreciseAndReadable).

Therefore:

Write each step to show clearly which actor is performing the action, and what the actor gets accomplished.

Minimize your writing effort by using a simple format for each step. We recommend a clear sentence with straightforward grammar: actor, verb, direct object, and prepositional phrase. “User enters name and address” or “System notifies user of results.” When the actor is visible in each step, then it is clear to both the reviewers and the developers which actor must perform the step. This reduces ambiguity and helps protect the project from the problems that arise from miscommunication.

Use active verbs in the present tense to describe each actor making ForwardProgress (p. 162) toward the goal. Each step, except those at the lowest level, should address a lower level CompleteSingleGoal (p. 118), so that if necessary, you can create an EverUnfoldingStory (p. 102) by converting the step's verb phrase into a lower level use case.

Examples

The Actor-less ATM

Having programmers write their own use cases often results in system-oriented scenarios such as the one shown in Use Case 6.8.

Although this scenario is clear to the writer, it leaves questions about what the customer's part is in the transaction. Use Case 6.9 is a better version of this use case because it clearly shows what the actor accomplishes.

This style clearly shows who is responsible for what action.

In a related style, some people like to write in the passive voice, again leaving out which actor is taking the initiative, such as in Use Case 6.10.

Unfortunately, different actors initiate the actions. Though the steps in Use Case 6.10 are leveled and show ForwardProgress (p. 162), it is not clear to anyone other than the writer who is responsible for doing what. Readers can only guess.

A final mistaken style of writing is to name many, even technology-specific, movements the user of the system will take. See Use Case 6.11.

Here we can improve the writing by combining the steps, making the use case TechnologyNeutral (p. 167), and capturing the intent of the actor instead of the technology-specific movements. The result is Use Case 6.12.

Level:

Civilian defense workers marching in full regalia in the Labor Day parade, Detroit, Michigan

ForwardProgress

You are writing the steps of a scenario as LeveledSteps (p. 153).

Writers have to decide how much behavior to put into any one step. They can easily write too much detail, making the use case long and tiring to read.

Creating a diversion is a simple plot technique to add conflict to what would otherwise be a very simple and straightforward story. Two or more rivals are pursuing a common goal and one of them attempts to slow or stop the other by creating a distraction. The “Star Trek” television series frequently used this technique. “Star Trek” would have been very uninteresting if all that happened when the Enterprise raced to answer a distress call from a damaged ship was that Captain Kirk and his crew rescued the troubled sailors and then headed off to the next starbase. To heat things up, chief engineer Scotty would shout his famous “She cannae take much mor o' this,” or the Romulans would send a fake distress call that would force the Enterprise to break off and race to the rescue. Suddenly the story would focus on the efforts of the Enterprise crew to overcome the diversion. The original goal of the rescue mission became almost an afterthought.

While diversions help create good stories, a good use case should tell a story in a straightforward and simple manner.

Clear, succinct steps lower the mental cost of understanding and evaluating a use case. Each step in a scenario needs to be germane, succinct, and clear, to make it as easy as possible for the reader to follow. If you put too much information into a single step, you increase the chance that the reader will lose track of what is happening inside that step, perhaps missing a key business or implementation issue. If you put too little information within a step, you will need more steps to tell the story, making the use case longer and more tedious to read.

A desire for completeness and detail may lead to the inclusion of steps that are tangential to the goal of the use case. People like to add details to use cases because they feel that extra information improves our understanding of unfamiliar issues. However, tangential steps are more likely to cause the reader to lose focus. A good use case is much like a good movie: well paced and tightly plotted. Extraneous scenes and tangential steps only serve to clutter the description. Worse, someone may try to implement the tangents, wasting time and benefiting no one. Even when the step adds value to the scenario, unnecessary or overly complex details can distract the reader from the main path.

Therefore:

Eliminate or merge steps that do not advance the actor. Simplify passages that distract the reader from this progress.

Writing long, complex, or tangential steps unnecessarily diverts the reader, who should instead see a clear progression within a scenario. Provide enough detail in each step to enlighten the reader of its purpose, but not so much that you describe the step in excruciating detail. Ensure that the steps stay relevant to the reader and that each step is a LeveledStep, contains a “bite-sized” amount of information, and shows the ActorIntentAccomplished (p. 158).

Many people have trouble reading technical documents because they are complex and contain a lot of unrelated details. Anything you can do to simplify your use cases (short of removing necessary information) will make them easier to use. If there are tangential steps that represent important alternatives, then incorporate them as alternatives to the scenario—ScenarioPlusFragments (p. 125). If there are details you believe are important to understanding the story, or are simply too important to lose, then attach them to the use case as Adornments (p. 133).

Examples

Wings Over the World: A Diversionary Scenario

The snippet of the Request Upgrade use case shown in Use Case 6.13 shows two blatant diversions in the main success scenario.

In this example, steps 2 and 5 are alternatives that divert attention away from the real story of how a traveler requests a seat upgrade. Step 2 is really an alternative to step 1, handling those instances where the customer is a frequent flier. Step 5 is an alternative available to step 4 when the traveler does not have enough upgrade certificates.

You can still show these diversions, but as alternatives. A better way to write this scenario appears in Use Case 6.14.

Insurance Claim: Not Enough Forward Progress

Use Case 6.15 shows a different example, in which the diversion is not as blatant as in the previous example but is still equally distracting. Its steps are not “leveled.” There is no explicit diversion but there is not enough forward progress either.

The tip-off here is that several steps in a row refer to the same actor performing one action after another. When you see this, consider whether there is enough forward progress being made in each step. Ask, as in getting LeveledSteps (p. 153), “What is the actor trying to accomplish?” and “Can I find a way to express all this information in a single step?”

In Use Case 6.15, steps 1 through 5 are a necessary part of the process, but they waste a lot of the reader's energy by making very little overall progress. It would be more succinct, easier to read, and just as informative to write:

  1. Claimant submits form with substantiating data.

Step 6 does not bring any forward progress to the use case; indeed, it is superfluous. Claimants may want to save copies of their claim forms (that is their prerogative). They may also want to post their insurance agent's picture on the wall for dart practice, or use one to line a birdcage. Again, that is their prerogative. These actions have nothing to do with the use cases; the insurance company will process their claim regardless. This step can be deleted.

Step 7 says, “checks whether.” This commonly used phrase shows only half of the needed action. The check will either succeed or fail. Saying “checks whether” implies that the writer must write another sentence saying what the outcome will be. However, a use case step shows accomplishment—in other words, that the check succeeds. A failure on the verification will show up in an extension condition. Therefore, steps 7 and 8 should be merged, becoming the shorter, clearer:

  1. Insurance company verifies that claimant owns a valid policy.

At this point, we can revise the preceding eleven-step scenario into a five-step scenario, in which each step carries its own weight, making distinct ForwardProgress toward a specific goal. The result is Use Case 6.16.

Level:

Testing the plumb of a bulkhead. Bethlehem-Fairfield shipyards, Baltimore, Maryland

TechnologyNeutral[*]

You are writing the steps of a scenario as LeveledSteps (p. 153), working to keep the use case PreciseAndReadable (p. 138).

Including technology constraints and implementation details in a use case description increases the complexity and obscures the goal of the use case.

One of the less popular tasks that software developers do is called “porting” a system, which involves taking a software system that exists on one hardware platform and changing it so that it can run on another. This task is often tedious because it involves redoing the same system several times. One reason that the Java programming language is so popular is that it provides a “compile-once, run-anywhere” feature that allows programmers to write a program once, then run it on any computer that supports Java. (Or “compile once, debug everywhere,” as some Java detractors say.) It accomplishes this feat by providing a standardized interface that hides the machine-dependent code from the programmers, so that programmers can call the interface without concerning themselves with platform-specific issues.

Good use cases should likewise insulate readers from system-specific details, leaving them free to focus on the system's essential behavior.

Many people like to think in concrete terms. While abstraction is key to good design, such thinking is difficult and requires a thorough understanding of the problem. People cannot abstract things they don't understand; instead, they seek concrete details to improve their knowledge. Only when they feel comfortable with a topic will they begin to think abstractly about it. It is not surprising that writers like to add low-level details to use cases, because they are often learning about the system as they write, and these details make them feel comfortable by giving them a better understanding of what they are doing.

Technology is volatile; including details about specific technologies will cause rework. Technology is constantly changing. Vendors are constantly releasing new versions of their products, as those of us who have bought a top-of-the-line computer that became obsolete within a matter of weeks will attest. In theory, these changes should not present a problem, because they are hidden within a product. Unfortunately, many of them subtly and visibly do affect the product's behavior. Consequently, use cases describing these kinds of details become obsolete whenever the product changes, forcing an organization to either perpetually update its use cases or use obsolete ones.

Technological details impose improper constraints on future activities. Implementation details can bias the readers to a particular design by masquerading as requirements. Worse, they assume an undue aura of importance because they often require explanatory text. For example, mentioning a file in a use case might force the writers to include extra error and alternative courses for handling the file, turning the focus of the use case toward file handling, rather than providing a UserValuedTransaction (p. 95).

Adding technological details increases the cost of both reading and writing use cases. Use cases should capture essential system behavior without delving into its low-level structure. When they leave out technical details, use cases speak to a wide range of audiences, technical and nontechnical alike. If the readers can easily grasp the system's purpose, then they are free to use their own imagination to flesh out those details, often coming up with a better, more creative solution than the use case implies.

Sometimes technology is a requirement. Product development doesn't occur in a vacuum. Often, a new system must be able to interact with existing systems using specific protocols or access common data using a specific database engine. The product may also have to meet industry or government standards. Somehow, you need to include this information.

Therefore:

Write each use case in a technology-neutral manner.

Focus on essential system behavior such as what actions the system performs, or why someone might want to do them. Describe specific actions in neutral ways, avoiding details that might guide the readers toward specific implementations. Be especially cautious about specific terminology, because common words such as database, file, or GUI can subtly guide developers toward specific design decisions. Use phrases such as “The user requests information from the system” instead of “The user selects the Open button from the File pull-down menu.” The former allows the developers the latitude to decide how best to store this information, while the latter leads them toward using files and a specific GUI. The developers may decide that a file is best after all, but that decision must come at a more appropriate time, when they have a better understanding of the system.

If there are implementation details and technology constraints that are relevant to the use case or help increase comprehension, then include these as Adornments (p. 133).

Examples

File Accident Claim: Tied to Technology

Developers constantly violate this guideline by tying their use cases to a particular graphical user interface (GUI). Yet this practice constrains the developers, and leads to a situation where the GUI drives use case development. But GUIs describe only a system's look and feel, not its behavior. Tying GUIs to use cases is putting the cart before the horse, because GUI developers should be using the use cases to help design the system interface, not the other way around.

Consider Use Case 6.17 for submitting a claim to an insurance office.

This example contains several flaws.

  1. It presupposes that the system will store policy information in a database.

  2. It presupposes that the system will store claim information in a data file.

  3. It presupposes that the system will send e-mail to acknowledge a claim.

  4. It presupposes that the system will use a specific form.

In short, this scenario makes some design assumptions. While these may or may not be requirements, they don't belong here. If they are not requirements, then they may prevent the developers from examining and implementing other, more efficient mechanisms for processing the claim.

For that reason, it is better to write the scenario as shown in Use Case 6.18.

This scenario describes the system's behavior without supplying any design information. It lists necessary information such as policy number and name, but it does not specify its format. It also informs readers that much of this data is persistent, but it doesn't tell them how it is stored. This format allows the developers to make these decisions in a manner that is best for the system.

It is incredibly easy to introduce implementation details into a scenario, and we often do so without realizing it. Just adding two seemingly innocent words to the end of Step 1—“via Internet”—completely changes the nature of this scenario.

  1. Claimant accesses Accident Reporting System via Internet.

While the phrase “via Internet” seems innocuous enough, it subtly focuses the reader's attention on a Web-based solution. But who said that the Internet is the best solution for this system? What about customers without Internet access, either because they don't have access to a computer or because they've suffered an accident that requires lengthy hospitalization? It is quite possible that such clients might not be able to report the accident until they return home. This case is of particular interest to insurance companies, however, because most of them wish to know immediately when their clients are hospitalized in order to control costs. These two simple words could lead the developers to devise a solution that is in conflict with their client's most important goal of reducing costs.

Trade-offs and Collaborations

Like the old proverb, “A chain is only as strong as its weakest link,” a use case is only as clear as its most ambiguous step. Organizing steps in scenarios and using a simple standard form for each step reduces the effort required in both reading and writing the individual step and the overall use case. The patterns in this chapter form the baseline for a simple standard form.

The two scenario patterns help us write ScenarioPlusFragments (p. 125). DetectableConditions (p. 148) tells us that we should describe only those kinds of situations that can really occur as the actors interact with the system. Otherwise, we waste our time writing scenarios that no one needs or that are redundant. Worse, someone may even try to implement the unnecessary scenarios, wasting valuable development time. LeveledSteps (p. 153) shows us how to balance our use cases so that no one scenario, especially an alternative one, can dominate. It recommends writing them in parallel styles so that the reader can easily follow them, without attaching undue importance to an overly complex one.

But leveling steps involves more than just writing steps with the same level of detail, and we have several patterns to guide us. Each step in a scenario must meet three conditions: First, it must add value by clearly making some ForwardProgress (p. 162) toward fulfilling the scenario's ultimate goal. Second, it must demonstrate purpose by showing the ActorIntentAccomplished (p. 158), showing who is trying to accomplish the action, and what it is that the actor is trying to accomplish. Last, it must be TechnologyNeutral (p. 167), neither bombarding the user with excessive details, nor implying a design. Steps that fail to meet all three of these conditions serve only to confuse the reader and add ambiguity to the scenario; they should be rewritten or removed from the scenario.

LeveledSteps is similar to EverUnfoldingStory (p. 102), bringing unity and parallelism to scenarios, just as EverUnfoldingStory does for a set of use cases. However, they are two different patterns, having different contexts and purposes. EverUnfoldingStory balances goal levels for sets of use cases, while LeveledSteps balances the content of individual scenarios. In fact, using LeveledSteps makes it easier to write an EverUnfoldingStory, because it is a fairly simple matter to expand a series of leveled steps into a set of lower level use cases.

These three chapters—“The Use Case Set,” “The Use Case,” and “Scenarios and Steps”—have described the structure of well-written use cases. Sometimes, however, our well-written use cases can violate these guidelines for reasons beyond our control. System boundaries can change and goals can shift, causing some use cases to become redundant or obsolete, or to address the wrong scope. The following chapters describe what you can do to restore order to your use cases when these situations occur.



[*] This pattern was influenced by Rick Ratliff's Sans GUI pattern from the OOPSLA 98 Use Case Patterns workshop.

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

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