Chapter 17. Use Cases

No system exists in isolation. Every interesting system interacts with human or automated actors that use that system for some purpose, and those actors expect that system to behave in predictable ways. A use case specifies the behavior of a subject—a system or a part of a system—it describes sequences of actions, including variants, that a subject performs to yield an observable result of value to an actor.

You apply use cases to capture the intended behavior of the system you are developing, without having to specify how that behavior is implemented. Use cases provide a way for your developers to come to a common understanding with your system's end users and domain experts. In addition, use cases serve to help validate your architecture and to verify your system as it evolves during development. As you implement your system, these use cases are realized by collaborations whose elements work together to carry out each use case.

Well-structured use cases denote essential subject behaviors only, and are neither overly general nor too specific.

Getting Started

A well-designed house is much more than a bunch of walls thrown together to hold up a roof that keeps out the weather. When you work with your architect to design your house, you'll give strong consideration to how you'll use that house. If you like entertaining, you'll want to think about the flow of people through your family room in a way that facilitates conversation and avoids dead ends that result in bunching. As you think about preparing meals for your family, you'll want to make sure your kitchen is designed for efficient placement of storage and appliances. Even plotting the path from your car to the kitchen in order to unload groceries will affect how you eventually connect rooms to one another. If you have a large family, you'll want to give thought to bathroom usage. Planning for the right number and right placement of bathrooms early on in the design will greatly reduce the risk of bottlenecks in the morning as your family heads to school and work. If you have teenagers, this issue has especially high risk, because the emotional cost of failure is high.

Reasoning about how you and your family will use your house is an example of use case-based analysis. You consider the various ways in which you'll use the house, and these use cases drive the architecture. Many families will have the same kinds of use cases—you use houses to eat, sleep, raise children, and hold memories. Every family will also have its own special use cases or variations of these basic ones. The needs of a large family, for example, are different from the needs of a single adult just out of college. It's these variations that have the greatest impact on the shape of your final home.

One key factor in creating use cases such as these is that you do so without specifying how the use cases are implemented. For example, you can specify how an ATM system should behave by stating in use cases how users interact with the system; you don't need to know anything about the inside of the ATM at all. Use cases specify externally visible behavior; they do not dictate how that behavior will be carried out internally. The great thing about this is that it lets you (as an end user and domain expert) communicate with your developers (who build systems that satisfy your requirements) without getting hung up on details. Those details will come, but use cases let you focus on the issues of highest risk to you.

In the UML, all such behaviors are modeled as use cases that may be specified independent of their realization. A use case is a description of a set of sequences of actions, including variants, that a subject performs to yield an observable result of value to an actor. There are a number of important parts to this definition.

At the system level, a use case describes a set of sequences, in which each sequence represents the interaction of the things outside the system (its actors) with the system itself (and its key abstractions). These behaviors are in effect system-level functions that you use to visualize, specify, construct, and document the intended behavior of your system during requirements capture and analysis. A use case represents a functional requirement of your system as a whole. For example, one central use case of a bank is to process loans.

A use case involves the interaction of actors and the system or other subject. An actor represents a coherent set of roles that users of use cases play when interacting with these use cases. Actors can be human or they can be automated systems. For example, in modeling a bank, processing a loan involves, among other things, the interaction between a customer and a loan officer.

A use case may have variants. In all interesting systems, you'll find use cases that are specialized versions of other use cases, use cases that are included as parts of other use cases, and use cases that extend the behavior of other core use cases. You can factor the common, reusable behavior of a set of use cases by organizing them according to these three kinds of relationships. For example, in modeling a bank, you'll find many variations among the basic use case of processing a loan, such as the difference in processing a jumbo mortgage versus a small business loan. In each case, however, these use cases share some degree of common behavior, such as the use case of qualifying the customer for the loan, a behavior that is part of processing every kind of loan.

A use case carries out some tangible amount of work. From the perspective of a given actor, a use case does something that's of value to an actor, such as calculate a result, generate a new object, or change the state of another object. For example, in modeling a bank, processing a loan results in the delivery of an approved loan, manifest in a pile of money handed to the customer.

You can apply use cases to your whole system. You can also apply use cases to part of your system, including subsystems and even individual classes and interfaces. In each case, these use cases not only represent the desired behavior of these elements, but they can also be used as the basis of test cases for these elements as they evolve during development. Use cases applied to subsystems are excellent sources of regression tests; use cases applied to the whole system are excellent sources of integration and system tests. The UML provides a graphical representation of a use case and an actor, as Figure 17-1 shows. This notation permits you to visualize a use case apart from its realization and in context with other use cases.

Actor and Use Case

Figure 17-1. Actor and Use Case

Terms and Concepts

A use case is a description of a set of sequences of actions, including variants, that a system performs to yield an observable result of value to an actor. Graphically, a use case is rendered as an ellipse.

Subject

The subject is a class described by a set of use cases. Usually the class is a system or subsystem. The use cases represent aspects of the behavior of the class. The actors represent aspects of other classes that interact with the subject. Taken together, the use cases describe the complete behavior of the subject.

Names

Every use case must have a name that distinguishes it from other use cases. A name is a textual string. That name alone is known as a simple name; a qualified name is the use case name prefixed by the name of the package in which that use case lives. A use case is typically drawn showing only its name, as in Figure 17-2.

Simple and Qualified Names

Figure 17-2. Simple and Qualified Names

Note

A use case name may be text consisting of any number of letters, numbers, and most punctuation marks (except for marks such as the colon, which is used to separate a class name and the name of its enclosing package) and may continue over several lines. In practice, use case names are short active verb phrases naming some behavior found in the vocabulary of the system you are modeling.

Use Cases and Actors

An actor represents a coherent set of roles that users of use cases play when interacting with these use cases. Typically, an actor represents a role that a human, a hardware device, or even another system plays with a system. For example, if you work for a bank, you might be a LoanOfficer. If you do your personal banking there, as well, you'll also play the role of Customer. An instance of an actor, therefore, represents an individual interacting with the system in a specific way. Although you'll use actors in your models, actors are not actually part of the software application. They live outside the application within the surrounding environment.

In an executing system, actors need not exist as separate entities. One object may play the part of multiple actors. For example, one Person may be both a LoanOfficer and a Customer. An actor represents one aspect of an object.

As Figure 17-3 indicates, actors are rendered as stick figures. You can define general kinds of actors (such as Customer) and specialize them (such as CommercialCustomer) using generalization relationships.

Actors

Figure 17-3. Actors

Note

You can use the UML's extensibility mechanisms to stereotype an actor in order to provide a different icon that might offer a better visual cue for your purposes.

Actors may be connected to use cases only by association. An association between an actor and a use case indicates that the actor and the use case communicate with one another, each one possibly sending and receiving messages.

Use Cases and Flow of Events

A use case describes what a system (or a subsystem, class, or interface) does but it does not specify how it does it. When you model, it's important that you keep clear the separation of concerns between this outside and inside view.

You can specify the behavior of a use case by describing a flow of events in text clearly enough for an outsider to understand it easily. When you write this flow of events, you should include how and when the use case starts and ends, when the use case interacts with the actors and what objects are exchanged, and the basic flow and alternative flows of the behavior.

For example, in the context of an ATM system, you might describe the use case ValidateUser in the following way:

  • Main flow of eventsThe use case starts when the system prompts the Customer for a PIN number. The Customer can now enter a PIN number via the keypad. The Customer commits the entry by pressing the Enter button. The system then checks this PIN number to see if it is valid. If the PIN number is valid, the system acknowledges the entry, thus ending the use case.

  • Exceptional flow of eventsThe Customer can cancel a transaction at any time by pressing the Cancel button, thus restarting the use case. No changes are made to the Customer's account.

  • Exceptional flow of eventsThe Customer can clear a PIN number anytime before committing it and reenter a new PIN number.

  • Exceptional flow of eventsIf the Customer enters an invalid PIN number, the use case restarts. If this happens three times in a row, the system cancels the entire transaction, preventing the Customer from interacting with the ATM for 60 seconds.

Note

You can specify a use case's flow of events in a number of ways, including informal structured text (as in the example above), formal structured text (with pre- and postconditions), state machines (particularly for reactive systems), activity diagrams (particularly for workflows), and pseudocode.

Use Cases and Scenarios

Typically, you'll first describe the flow of events for a use case in text. As you refine your understanding of your system's requirements, however, you'll want to also use interaction diagrams to specify these flows graphically. Typically, you'll use one sequence diagram to specify a use case's main flow, and variations of that diagram to specify a use case's exceptional flows.

It is desirable to separate main versus alternative flows because a use case describes a set of sequences, not just a single sequence, and it would be impossible to express all the details of an interesting use case in just one sequence. For example, in a human resources system, you might find the use case Hire employee. This general business function might have many possible variations. You might hire a person from another company (the most common scenario); you might transfer a person from one division to another (common in international companies); or you might hire a foreign national (which involves its own special rules). Each of these variants can be expressed in a different sequence.

This one use case (Hire employee) actually describes a set of sequences in which each sequence in the set represents one possible flow through all these variations. Each sequence is called a scenario. A scenario is a specific sequence of actions that illustrates behavior. Scenarios are to use cases as instances are to classes, meaning that a scenario is basically one instance of a use case.

Note

There's an expansion factor from use cases to scenarios. A modestly complex system might have a few dozen use cases that capture its behavior, and each use case might expand out to several dozen scenarios. For each use case, you'll find primary scenarios (which define essential sequences) and secondary scenarios (which define alternative sequences).

Use Cases and Collaborations

A use case captures the intended behavior of the system (or subsystem, class, or interface) you are developing, without having to specify how that behavior is implemented. That's an important separation because the analysis of a system (which specifies behavior) should, as much as possible, not be influenced by implementation issues (which specify how that behavior is to be carried out). Ultimately, however, you have to implement your use cases, and you do so by creating a society of classes and other elements that work together to implement the behavior of this use case. This society of elements, including both its static and dynamic structure, is modeled in the UML as a collaboration.

As Figure 17-4 shows, you can explicitly specify the realization of a use case by a collaboration. Most of the time, though, a given use case is realized by exactly one collaboration, so you will not need to model this relationship explicitly.

Use Cases and Collaborations

Figure 17-4. Use Cases and Collaborations

Note

Although you may not visualize this relationship explicitly, the tools you use to manage your models will likely maintain this relationship.

Note

Finding the minimal set of well-structured collaborations that satisfy the flow of events specified in all the use cases of a system is the focus of a system's architecture.

Organizing Use Cases

You can organize use cases by grouping them in packages in the same manner in which you can organize classes.

You can also organize use cases by specifying generalization, include, and extend relationships among them. You apply these relationships in order to factor common behavior (by pulling such behavior from other use cases that it includes) and in order to factor variants (by pushing such behavior into other use cases that extend it).

Generalization among use cases is just like generalization among classes. Here it means that the child use case inherits the behavior and meaning of the parent use case; the child may add to or override the behavior of its parent; and the child may be substituted any place the parent appears (both the parent and the child may have concrete instances). For example, in a banking system, you might have the use case Validate User, which is responsible for verifying the identity of the user. You might then have two specialized children of this use case (Check password and Retinal scan), both of which behave just like Validate User and may be applied anywhere Validate User appears, yet both of which add their own behavior (the former by checking a textual password, the latter by checking the unique retina patterns of the user). As shown in Figure 17-5, generalization among use cases is rendered as a solid directed line with a large triangular arrowhead, just like generalization among classes.

Generalization, Include, and Extend

Figure 17-5. Generalization, Include, and Extend

An include relationship between use cases means that the base use case explicitly incorporates the behavior of another use case at a location specified in the base. The included use case never stands alone, but is only instantiated as part of some larger base that includes it. You can think of include as the base use case pulling behavior from the supplier use case.

You use an include relationship to avoid describing the same flow of events several times, by putting the common behavior in a use case of its own (the use case that is included by a base use case). The include relationship is essentially an example of delegation—you take a set of responsibilities of the system and capture it in one place (the included use case), then let all other parts of the system (other use cases) include the new aggregation of responsibilities whenever they need to use that functionality.

You render an include relationship as a dependency, stereotyped as include. To specify the location in a flow of events in which the base use case includes the behavior of another, you simply write include followed by the name of the use case you want to include, as in the following flow for Track order:

Track order:
 obtain and verify the order number;
 include 'Validate user';
 for each part in the order,
  query the order status;
 report overall status to user.

Note

There is no predefined UML notation for expressing use case scenarios. The syntax used here is a kind of structured natural language. Several authors have suggested that an informal notation is best, because use cases should not be regarded as rigid specifications that generate code automatically; others have proposed formal notations.

An extend relationship between use cases means that the base use case implicitly incorporates the behavior of another use case at a location specified indirectly by the extending use case. The base use case may stand alone, but under certain conditions its behavior may be extended by the behavior of another use case. This base use case may be extended only at certain points called, not surprisingly, its extension points. You can think of extend as the extension use case pushing behavior to the base use case.

You use an extend relationship to model the part of a use case the user may see as optional system behavior. In this way, you separate optional behavior from mandatory behavior. You may also use an extend relationship to model a separate subflow that is executed only under given conditions. Finally, you may use an extend relationship to model several flows that may be inserted at a certain point, governed by explicit interaction with an actor. You may also use an extend relationship to distinguish configurable parts of an implementable system; the implication is that the system can exist with or without the various extensions.

You render an extend relationship as a dependency, stereotyped as extend. You may list the extension points of the base use case in an extra compartment. These extension points are just labels that may appear in the flow of the base use case. For example, the flow for Place order might read as follows:

Place order:
 include 'Validate user';
 collect the user's order items;
 set priority: extension point;
 submit the order for processing.

In this example, set priority is an extension point. A use case may have more than one extension point (which may appear more than once), and these are always matched by name. Under normal circumstances, this base use case will execute without regard for the priority of the order. If, on the other hand, this is an instance of a priority order, the flow for this base case will carry out as above. But at the extension point set priority, the behavior of the extending use case Place rush order will be performed, then the flow will resume. If there are multiple extension points, the extending use case will simply fold in its flows in order.

Note

Organizing your use cases by extracting common behavior (through include relationships) and distinguishing variants (through extend relationships) is an important part of creating a simple, balanced, and understandable set of use cases for your system.

Other Features

Use cases are classifiers, so they may have attributes and operations that you may render just as for classes. You can think of these attributes as the objects inside the use case that you need to describe its outside behavior. Similarly, you can think of these operations as the actions of the system you need to describe a flow of events. These objects and operations may be used in your interaction diagrams to specify the behavior of the use case.

As classifiers, you can also attach state machines to use cases. You can use state machines as yet another way to describe the behavior represented by a use case.

Common Modeling Techniques

Modeling the Behavior of an Element

The most common thing for which you'll apply use cases is to model the behavior of an element, whether it is the system as a whole, a subsystem, or a class. When you model the behavior of these things, it's important that you focus on what that element does, not how it does it.

Applying use cases to elements in this way is important for three reasons. First, by modeling the behavior of an element with use cases, you provide a way for domain experts to specify its outside view to a degree sufficient for developers to construct its inside view. Use cases provide a forum for your domain experts, end users, and developers to communicate to one another. Second, use cases provide a way for developers to approach an element and understand it. A system, subsystem, or class may be complex and full of operations and other parts. By specifying an element's use cases, you help users of these elements to approach them in a direct way, according to how they are likely to use them. In the absence of such use cases, users have to discover on their own how to use those elements. Use cases let the author of an element communicate his or her intent about how that element should be used. Third, use cases serve as the basis for developing tests for each element as it evolves during development. By deriving tests from use cases and applying them repeatedly, you continuously validate the implementation. Not only do these use cases provide a source of regression tests, but every time you throw a new use case at an element, you are forced to reconsider your implementation to ensure that this element is resilient to change. If it is not, you must fix your architecture appropriately.

To model the behavior of an element,

  • Identify the actors that interact with the element. Candidate actors include groups that require certain behavior to perform their tasks or that are needed directly or indirectly to perform the element's functions.

  • Organize actors by identifying general and more specialized roles.

  • For each actor, consider the primary ways in which that actor interacts with the element. Consider also interactions that change the state of the element or its environment or that involve a response to some event.

  • Consider also the exceptional ways in which each actor interacts with the element.

  • Organize these behaviors as use cases, applying include and extend relationships to factor common behavior and distinguish exceptional behavior.

For example, a retail system will interact with customers who place and track orders. In turn, the system will ship orders and bill the customer. As Figure 17-6 shows, you can model the behavior of such a system by declaring these behaviors as use cases (Place order, Track order, Ship order, and Bill customer). Common behavior can be factored out (Validate customer) and variants (Ship partial order) can be distinguished as well. For each of these use cases, you would include a specification of the behavior, either by text, state machine, or interactions.

Modeling the Behavior of an Element

Figure 17-6. Modeling the Behavior of an Element

As your models get bigger, you will find that many use cases tend to cluster together in groups that are conceptually and semantically related. In the UML, you can use packages to model these clusters of classes.

Hints and Tips

When you model use cases in the UML, every use case should represent some distinct and identifiable behavior of the system or part of the system. A well-structured use case

  • Names a single, identifiable, and reasonably atomic behavior of the system or part of the system.

  • Factors common behavior by pulling such behavior from other use cases that it includes.

  • Factors variants by pushing such behavior into other use cases that extend it.

  • Describes the flow of events clearly enough for an outsider to easily understand it.

  • Is described by a minimal set of scenarios that specify the normal and variant semantics of the use case.

When you draw a use case in the UML,

  • Show only those use cases that are important to understand the behavior of the system or the part of the system in its context.

  • Show only those actors that relate to these use cases.

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

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