Extending Use Cases

Extending Use Cases

Your use-case diagrams can convey lots of information packed into a simple form—but most information developed in the analysis stage ends up inside the use case, serving as its specifications (discussed more fully in Chapter 9). In practice, use-case flows get much of their true complexity from the entanglement of multiple alternate courses and paths.

When you draw use-case diagrams, you’re practicing the good object-oriented principles of abstraction and information hiding (as described in Chapter 2) to simplify the tangle—communicating the essence without the distraction of suppressible details.

Hiding complexity is generally good, but sometimes you have to expose some details to gain clarity somewhere else. With UML, you can depict important alternate flows graphically by making them into their own use cases. Then you can connect these new use cases to their base use cases by establishing an «extend» relationship. Thus, you can emphasize otherwise-hidden information when the reviewers of your use-case diagram want to see it. Some reasons this might be desirable are as follows:

  • Changed capability: If you have changed a use case significantly— perhaps because of a later release—you may find it useful (and perhaps politic) to emphasize that the change has occurred, rather than burying it in the use-case specification.

  • Major variation: If you have a major alternative path in the use case, and it’s complex enough to have its own alternative paths, then placing it on your diagram will honestly expose the complexity—which is helpful in costing, assignment, and scheduling.

  • Optional subgoal: If you have parts of the use case that would be optional to implement (or even optional to execute) to meet the actor’s goals, put those parts into their own use case. Doing so clarifies the relationships between actors and their goals. It also emphasizes that you may deliver these optional goals in later releases.

Showing a new release

When you have significantly changed a capability in a new release (a new delivery of code to the users), it’s often best to create a new extension use case that extends the existing use case. Figure, for example, shows Make Room Reservation V2.0 as an extension use case of the original Make Room Reservation. The «extend» relationship uses an open-headed, dashed arrow that points from the extension to the base use case.

When you document the changes in such an extension use case, you save yourself the work of changing any existing documentation. In fact, it’s considered incorrect for a base use-case specification (the textual description discussed in Chapter 9) to mention that it’s extended (except for listing extension points, as discussed in a moment). This prohibition supports encapsulation—so you can extend at whim without having to change any existing use cases. As an added bonus, you shield your existing use cases from extra review or criticism.

Figure: Showing a new release.

 Warning   When you use extensions to indicate additional releases of a use case, you may find yourself in a common methodological quandary: The extension use case is only supposed to capture any differences from the base use case. The idea is to avoid duplicating things unnecessarily. On the other hand, documenting a second-release use case without duplication is sometimes difficult, especially if lots of small changes have cropped up within the use case.

Using extension to show a new release also introduces a maintenance problem. After a while, you may end up with a chain of extended use cases—Make Room Reservation 3.0 extending Make Room Reservation 2.0 and so on. No subsequent use case can then be understood without understanding the previous use case. This situation will undoubtedly cause problems.

And no, there are no ideal solutions to those problems. Therefore, we generally recommend that you document subsequent releases as shown in Figure.

Figure: Documenting New Releases

Extent of New Release

Documentation Approach

Very small (or small diffuse changes), throughout the use

Modify your existing use-case documentation. Use change bars (or equivalent) to indicate new case requirements or approaches for the next release.

Small, compact changes.

Use alternate flows or courses to indicate new requirements or approaches for the next release.

Large, compact changes.

Create an extension use case to indicate alternative flows found in the next release.

Large, diffuse changes.

Create generalized use case for common behavior, and then create specialized use cases for current and future releases.

Taking alternate paths

You’ll often have situations in which a use case takes an alternate path or course (based on some circumstances or condition) but still attempts to reach the original goal. In Chapter 9, we explain that an alternative course is a variation in the path of the use-case flow caused by some condition. For example, when a Potential Guest Makes a Room Reservation, the user who wants the room may come to the point at which the system prompts for any affinity plans (such as frequent-traveler, hotel, or airline-mileage plans) in which the user participates. Not only may extra points be available for each stay, but also a Potential Guest enrolled in the right plans can get a room upgrade.

This activity of upgrading the reservation is an alternate path on the way to reserving a room that only happens at a specific point in the use case—while the actor is entering the affinity plans, and only under specific conditions—the plan being entered is the right (eligible) plan. It’s also a complex alternate path—there are usually restrictions on how and when an upgrade may be obtained, and usually a guest must have (or trade) a certain minimum number of points for the upgrade. Thus upgrading has its own alternate paths.

Not only is it complex, this path is not really necessary to achieve the main goal of Make Room Reservation. This makes it a good candidate to pull it out of the Make Room Reservation use case and document it as a separate use case. This new use case that we pull out, Upgrade Reservation, UML calls an extension use case, because it extends the original (or base) use case with new capabilities or flows.

The place in the original (base) use case where the extension use case was inserted (or as you may think of it, where the extension use case came from), is called the extension point.

A dashed arrow pointing from the extension to the base connects the base use case and extension use case. Label the arrow with the stereotype of «extend». Figure shows the ongoing example.

Figure: An extension and extension points.

 Warning   Almost everyone is initially confused about the direction of the «extend» arrow. It points from the new extension use case to the base, in the opposite way from that of the «include» relationship discussed earlier. In Figure, you should read the relationship as, “Upgrade Reservation extends Make Room Reservation”, or if you prefer reading in the other direction, “Make Room Reservation is extended by Upgrade Reservation”.

Besides the basic notation for the «extend» relationship, there is some optional UML notation that you may find useful. In the lower section of the oval that represents the base use case, you can list the extension points—places where extension use cases may be inserted. Each of these identifies a step (or range of steps) in the flow of events in the base use case shown in Chapter 9. The numbering techniques given in that chapter to identify the location of an alternate course can be used to identify the location of the extension points (for example, Main Course Step 5; Alternate Course 2, Steps 3-6). To avoid exposing the inner details of the step numbering (which would require the diagram to change too often), we recommend that you use a easily remembered name for each extension point. This name should be mapped to the step numbers in the specification for the base use case. In Figure, for example, the extension point is identified as Entering Affinity Plans.

 Tip   Another way of identifying an extension point is to refer to the name of the activity that the use case must be executing when the extension is inserted. Check out Chapter 13 for using UML activity diagrams to diagram the steps of a use case.

The figure also shows how you can attach to the «extend» relationship a comment indicating the condition under which the extension applies. To completely read the diagram with the optional UML notation, it would go something like this: “Upgrade Reservation extends Make Room Reservation when the condition {Customer is in an acceptable affinity plan} is true at the point the Make Room Reservation reaches the extension point Entering Affinity Plans”.

Extending with optional goals

Believe it or not, you may have to add an activity to a use case that’s not needed to achieve its goal. For example, you may want to request that any Potential Guest answer a marketing survey when making a room reservation (as in Figure). This may become a mandatory insertion, but it’s optional to the actor’s goals—you could, in theory, eliminate it—so it’s best modeled as an extension.

Figure: Mandatory use case with optional goal.

Misusing extends

You may have problems determining when to employ extensions (as opposed to other techniques such as inclusion or generalization discussed earlier in this chapter). Unfortunately, the advice typically given isn’t sufficient to end controversy. You’re usually told that the extension use cases must be optional when invoked from their base use cases—and that the extension use cases cannot depend on their base use cases.

One problem with such pronouncements is that the term optional isn’t well defined. There are at least two possible meanings here. An extension use case could be optional to implement or optional to execute at runtime. Most practitioners prefer the second approach because it seems easy to see whether a use case has a condition to test before it executes. For many use cases, however, it’s hard to define whether something is truly optional to execute. For example, if the runtime test is always true, is the use case really optional to run? And if you can’t decide which course is the main course and which is an alternative course, would a use case be an extension if it’s used by the alternative course—but considered included if it’s used by the main course?

Okay, we do have some subtle reasons to believe it’s better to interpret optional to mean optional to implement. For openers, we believe that UML directed arrow requires that base use case not depend on extension use cases, but a base use case can depend on included use case. If you follow this guideline, your use-case diagram can (and should) determine required implementation order. This approach leads to two other clear requirements:

  • You must deliver any included use case along with its base use case.

  • You may deliver any extended use case later than its base use case.

Not only is this information valuable for scheduling work, it’s easy to understand visually.

On the other hand, we’ve seen civilized discussions on whether a use case should be an extension or an inclusion become disagreements, then arguments, and ultimately—well, they can cost your project a lot of time, money, and good will. You’re probably best off if you don’t take a hard line on such issues; this chapter’s three guidelines for extending use cases (listed earlier) will steer you in an effective direction.

 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows