Fast Track UML 2.0
The following guidelines have proven useful in producing tight, easy-to-understand use cases in a variety of contexts:
-
Use active voice, and speak from the actor's perspective. For some reason, engineers and other technically inclined people tend to rely heavily on passive voice: "The connection is made," "The item is selected by the customer," and so forth. You should always express use cases in active voice. After all, you wouldn't expect to see a user manual written in passive voice, and there's a direct correlation between use cases and user manual text. (The most significant difference is that the latter is written in what's called the second-person imperative, with an unspoken "you," whereas use case text is written in the third person, in terms of specific actors and the system.)
-
Use present tense. Requirements are usually written in the future tense: "The system shall do this and that," "The throughput of the system shall meet the following parameters." Each sentence of a use case should appear in the present tense: "The Customer selects the item," "The system makes the connection." This includes the text for alternate courses. (For example, "If the Customer selects a different item, the system comes to a grinding halt.") Keeping all the text in a consistent form makes it easier for its readers to trace the different paths through the basic course and alternate courses.
-
Express your text in the form of "call and response. " The basic form of your use case text should be "The [actor] does this" and "The system does that." The actor may do more than one thing consecutively, and the same holds true for the system, but the text should reflect the fact that the actor performs some action and the system responds accordingly . There shouldn't be any extraneous text.
-
Write your text in no more than three paragraphs. One of the guiding principles of object-oriented design is that a class should do a small number of things well, and nothing else. Why not adhere to this principle with use cases as well? A use case should address one functional requirement, or perhaps a very small set of requirements, and do it in a way that's obvious to anyone who reads it. Anything more than a few paragraphs, and you probably have a candidate for another use case. (See the section "Organizing Use Cases," later in the chapter, for a discussion of how to break up and organize use cases.) A sentence or two, however, is a signal that you don't have enough substance in your use case. Each use case should be a small, mobile unit that lends itself to possible reuse in other contexts.
-
Name your classes. There are two basic kinds of classes that lend themselves to inclusion in use case text: (a) those in the domain model (see the section "Domain-Level Class Diagrams" in Chapter 3) and (b) "boundary" classes, which include those windows , HTML pages, and so on that the actors use in interacting with the system. Down the line, it's going to be easier to design against text such as "The Customer changes one or more quantities on the Edit Contents of Shopping Cart page" and "The system creates an Account for the Customer" than against less-specific text (for example, "The Customer enters some values on an HTML page"). Be careful, though, to avoid including design details. You wouldn't talk about, say, the appearance of that HTML page or exactly what happens when the system creates an Account. The idea is to provide just enough detail for the designers to understand what's needed to address the basic requirements spelled out by the use cases.
-
Establish the initial context. You have to specify where the actor is, and what he or she is looking at, at the beginning of the use case. There are two ways to do this. The first way involves specifying the context as part of the first sentence: "The Accountant enters his or her user ID and password on the System Login window," for example. The second way involves defining a precondition: "The Accountant has brought up the System Login window." Doing this also makes it easier for someone to piece together the larger picture across a set of use cases.
-
Make sure that each use case produces at least one result of value to one or more actors, even if that result is negative. It's important to remember that a use case can't just end floating in space ‚ something measurable has to happen. Of course, this is generally some positive result: "The actor is logged in to the system," "The system completes the actor's task by updating the database," "The system generates a report." A use case can end on an alternate course of action, though, so "The system locks the user out of the system and sends an email to the system administrator" is also a viable result, even though it's hardly a desirable one.
-
Be exhaustive in finding alternate courses of action. A lot of the interesting behavior associated with a system can be nicely captured within alternate courses ‚ and it's a well-established principle that it's a lot cheaper to address this kind of behavior early in a project rather than later. A highly effective, if sometimes exhausting, way to root out alternate courses is to "challenge" every sentence of the basic course. In other words, ask repeatedly, "What can the actor do differently ‚ or wrong ‚ at this point?" or "What can go wrong internally at this point?" Remember two things while you're doing this. First, you don't need to account for generic failure conditions ‚ network down, database inaccessible ‚ within each use case; focus on those things that might happen in the specific context of the use case. Second, remember to take into account not only the novice/unsophisticated user but also the malicious user, the person who tries things he or she shouldn't just to see what might happen.
There are a couple of good methods for pointing to alternate courses from within the basic course. One surefire way to signal the presence of an alternate course involves using words such as validates , verifies , and ensures within the basic course. Each time one of these words appears, there's at least one associated alternate course, by definition, to account for the system's inability to validate, verify, or ensure the specified condition. For example, the basic course might say, "The system verifies that the credit card number that the Customer entered matches one of the numbers it has recorded for that Customer," while the corresponding alternate course might read, "If the system cannot match the entered credit card number to any of its stored values, it displays an error message and prompts the Customer to enter a different number." Another way to indicate the presence of an alternate course involves using labels for the alternate courses and then embedding those labels in the basic course. For example, an alternate course might have a label A1, and that label would appear in parentheses after the relevant statement(s) in the basic course.