• No results found

CREATED/PUBLISHED 1942 Mar

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

Use cases that are too complicated for non-technical 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

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 easily follow. Likewise, lower level audiences like developers will not use them if they contain too much “fluff”, or fail to adequately describe the system. 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, as they haven’t full 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.

Non technical stakeholders are likely to miss necessary considerations. Non-technical people have difficulty understanding highly technical documentation. Those without an understanding of the problem domain are unlikely to make the proper inferences from it, as 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 accuracy of the requirements. One of the greatest benefits of use cases is that they make it easy for stakeholders, many of whom are non-technical, 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 better describe the system 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 view’s (ParticipatingAudience(53)).

Dual-models are unacceptable because they can become disjoint and are difficult to

developers is project nightmare. Projects are under too much pressure to maintain two sets off documentation. It is inevitable that these will documents will become disjoint and difficult to maintain. . Not only is updating multiple copies of a document unnecessary, tedious and time consuming; it 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 they are 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 customers bother to read and evaluate it, and precise enough so that the implementers understand what they are building.

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

The cardinal rule for writing is "know your audience". Determine who needs these use cases, and write each one using their terminology in a style that they can easily understand. A less technical audience needs to understand the rationale for each action you describe, so write each step with VisibleActorIntent(161). 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 one.

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 text to describe essential system behavior. Include only that information necessary to describe the system’s behavior, but describe the behavior clearly and precisely enough so that an uninformed reader can fully understand the consequences of the behavior, without missing important events. This precision not only benefits the customers, but the developers as well, as they should not have to make guesses when building the system.

Use ExhaustiveAlternatives(140) to describe all situations that the actor can reasonably expect to encounter, as well as what actions the system should take to resolve them. The resolution should be complete enough to give the developer a good handle on what to do, but not so detailed that it spells out every action to the nth degree; it must be TechnologyNeutral(177).

Wings Over the World(1) Readable but Imprecise

Ralph is the Wings billing expert who believes that formality in writing use cases is just busy work that is delaying 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.

Use Case: Change Seat

PRIMARYACTORS: Traveler – Person flying on airplane.

LEVEL USERGOAL Change Seat Actor: Traveler

Main Course

The traveler specifies their seat preference and the system re-assigns them the new seat.

Alternatives:

Traveler is not eligible for a seat change.

Traveler is informed that a seat change is not available.

Use Case 1-5 Informal Version of Change Seat.

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 work group, 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(63), QuittingTime(71)).

On the other hand, the Wings project is being outsourced and this brief does not provide enough precision for a distant team to correctly implement this feature.

Wings Over the World(2) Precise but Unreadable

While imprecision results in ambiguity, excessive precision results in unusable use cases.

Ahmed the Chief Architect 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 were too imprecise for specifying constraints on objects. He has used OCL to describe the rules for seat change eligibility:

t : Traveler f: Flight

t.seatAssignment->notEmpty and t.ticketClass = #J or t.ticketClass = #Y

Ahmed’s 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 then the less opportunity there is for misunderstanding on the part of the developers. Some software developers believe that use of formal languages in specifications can greatly reduce the potential for ambiguity in the specifications.

But this level of precision is too complex for most readers to follow2. Often the real problem may not be the different interpretations of the requirements that stake holders and desingers may have as a result of using natural language. Rather, the greater risk may be that the project’s stake holders 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 has the ability to clearly understand the language, and few people are willing to admit they cannot understand a spec.

A good specification is one that you can present to the stakeholders that they can read and 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 tells you in a hesitant manner after reading the specification, “Well, ok, I guess so. You’re the expert in this stuff after all”, then you are heading for trouble. This response can indicate that the stakeholder did not understand the specification and is withdrawing, leaving you holding the bag.

It has been our observation that higher levels of formality in specifications give the developers a false sense of security that there is less opportunity for problems resulting from ambiguity. Nothing can replace a good on going dialog with the stakeholders.

1.7 Tradeoffs 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 they might take to get there, as well as those situations that could cause them to fail. It is primarily organizational in nature, providing order and structure so that the reader is able to easily identify and follow the different paths, or scenarios, as the actor progresses towards his goal.

UserValuedTransactions(110) tells us to capture the smallest set of goals that deliver all necessary services to the actors. A well-written use case provides a story describing how the system helps the primary actor completely reach a particular goal, a CompleteSingleGoal(132). 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. A use case that addresses a partial goal will likely force the reader 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(132)s, and we have identified several patterns (Figure 1-2) 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(136). The scenario describes a singular and complete sequence of events that the actor follows as they attempt to achieve some goal, and results in either success or failure. The fragments are a list of ExhaustiveAlternatives(140) 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 effort involved.

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

A meaningful use case name is also important. Every use case should have an IntentionRevealingName(144) 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(132). If the goal changes, you should consider changing the name as well, or if you want to change 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

Finally, a use case should be PreciseAndReadable(152), 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 present a moving target, so it is important that you know your audience when writing each one.

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 the users 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(132) and ScenarioPlusFragments(136) 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.

The Use Case Set

VerbPhraseName

ScenarioPlusFragment s

IntentionRevealingName PreciseButReadable

Each Use Case

UserValuedTransaction

CompleteSingleGoal

ScenarioPlusFragments

Adornments ExhaustiveAlternatives

Figure 1-2

1 Scenarios and Steps

Telling a Good Story

There are few cities in the world where you can still get a terrific corned beef sandwich like you can in New York. Despite the great outdoors life style the West Coast offers, it still has not learned the fine art of the deli lunch. It almost makes what you have had to endure for the last twenty-four hours worthwhile. A Red Eye flight from the coast, spending the morning tearing poor Ahmed’s use cases apart, and now you are about to do the same to poor Sitra, Wings Over the World’s resident RAPIER expert. Sitra is much like Ahmed, probably less than three years out of school, very smart, very eager to try out new technology. It also appears that Ahmed has warned her about “the consultant”.

Sitra: Ahmed said that you shredded his use case.

You: Shredding wasn’t my intention, we shortened it and made it more useful.

Sitra: That’s what Ahmed said also, so I shouldn’t be afraid of this. He was really happy with the results and he says that you can really help us.

You: OK I was looking at your Reserve Flight Segment use case and it has a lot of the same issues that I discussed with Ahmed such as the inclusion of business rules and excessive precision. I see Ahmed talked you into using OCL as well. The intention to make the use cases more precise is good, but it is inappropriate. There are also a few other things, for the most part this use case is quite low level – most of what this is a description of the physical protocol between you and RAPIER.

Sitra: That’s true, and most of my other use cases are like this one, they describe a transaction with RAPIER. But that’s important because just about everything we do must go through RAPIER, and my subsystem provides a wrapper around it.

You: Fair enough, but consider this, Reserve Flight Segment is really a single step in the Book Flight use case.

Sitra: Yes, but it’s a lot more complicated than that, the request can be rejected for a number of reasons, or even fail, and I thought the use cases were such a nice mechanism for capturing that.

You: I agree, but a big problem with this use case is that the steps are all at varying levels of abstraction. Some are at a business level for example, you have one step here– traveler selects flight – and then other steps are down to almost the program level – system formats

do not have to do mental calisthenics jumping back and forth between the different levels of abstraction. The essence of Reserve Flight Segment is to send a message to RAPIER to make a reservation on a single flight. RAPIER is either able to make the reservation or it is unable to do so. The essence of this use case is about three or four steps.

Sitra: Yes that may be true but it is a lot more complicated than that, you have to first set up a transaction with RAPIER, then format a request, send the request, decode the response.

There are literally dozens of return codes…

You: OK, but that is not necessarily what we want to capture in a use case. What you have here is 20 pages of prose that as a use case I can distill down into about three or four steps, plus a couple of alternatives. That is the essence of the Reserve Flight Segment use case.

Sitra: But what about everything else, that’s the meat of the problem. I can’t design a RAPIER interface subsystem from four sentences of prose.

You: Of course not, but the same thing I told Ahmed applies here, we can use the use case as an anchor for all the details, business rules, protocol specifications, technical constraints are supplements to the use case. I tend to call these Adornments(147). Ninety percent of this use case is a protocol description. Maybe you want to draw a state transition diagram that would more succinctly describe the protocol. Also, what you have done, is tied this use case to the RAPIER implementation. Really the use case should be TechnologyNeutral(177), after all we’re trying to capture the system essence, not its implementation. I would publish the RAPIER interface as a separate external interface document and then reference it from the use case.

Sitra: So that way if we want to work with another airline reservation system, our model is not tied to one specific implementation?

You: That’s right, the essence is still there, but if you have to change protocols then only that portion of the model is affected. Also this approach will reduce the number of alternatives your use case has. Right now you have some twenty alternatives, most of them based on the return code that you receive from RAPIER. But from what I can see there are really only three outcomes, either one, you were able to reserve the segment, two, you could not book the segment because space is unavailable, or three you could not book the segment because of a system failure. That’s it. But you have twenty alternatives. Ahmed had the same problem because he had incorporated the business rules into his use case, and had an alternative for

You: That’s right, the essence is still there, but if you have to change protocols then only that portion of the model is affected. Also this approach will reduce the number of alternatives your use case has. Right now you have some twenty alternatives, most of them based on the return code that you receive from RAPIER. But from what I can see there are really only three outcomes, either one, you were able to reserve the segment, two, you could not book the segment because space is unavailable, or three you could not book the segment because of a system failure. That’s it. But you have twenty alternatives. Ahmed had the same problem because he had incorporated the business rules into his use case, and had an alternative for