Chapter 10. Here There Be Dragons

Those of you with some prior exposure to use-case modeling may have won-dered why we have waited ten chapters to describe relationships in the use-case model other than simple communication between actors and use cases. There are several reasons, the most compelling of which is that the behavior of most systems can be described by collections of simple use cases that interact with their actors but otherwise have no other relationships. A more subtle reason is implied by the title of this chapter (taken from the warnings on old maps that dangers lie beyond). If there is one thing that sets teams down the wrong path, it is the misuse of the use-case relationships include, extend, and generalization.

It’s uncertain why teams have such difficulty with these relationships. Perhaps we can blame it on a long tradition in Western culture of breaking big problems into smaller problems to make their solution easier. This approach works well when working with problems, but a use case is not a problem statement, it is the description of a solution to some problem. Breaking a solution description into component parts can sometimes help, but mostly it makes the solution harder to understand. If we break big use cases down into smaller and smaller use cases, we end up with a situation where we can no longer see the solution—it is too fragmented to understand. When this happens, we lose the value of use cases. They can no longer to be used to confirm our understanding of the solution, and they can no longer serve as a common language for all the stakeholders. The goal of the use case is to create shared understanding; in order to do so it must be understandable.

We have seen teams spend lots of time structuring the use-case model under the mistaken assumption that the structure of the model will have some significant effect on the architecture of the system. It won’t, except to the extent that a system that has confusing and poorly understood requirements will probably also have a confusing and poorly understood architecture. Good systems have a purpose that is easy to understand and, more important, one that is understood by all members of the team. The structure of the use-case model bears no relationship to the architecture of the system under development. An overly structured use-case model obscures, rather than reveals, the real purpose of the system.

So, if the relationships between use cases are not meant to help us design the system, what is their intent? If they are to be useful at all, they must help us to better understand what the system is supposed to do. The focus of this chapter is to present the conditions under which creating relationships between use cases will aid understanding and to discuss the situations in which their careless use can lead to significant problems.

Using Named Subflows and Alternative Flows to Structure Text

As discussed in Chapter 8, named subflows and alternative flows provide powerful techniques for structuring a use case’s flow of events without resorting to creating relationships between the use cases. Named subflows allow reuse of common behavior within a single use case and often foreshadow the introduction of included behavior when the same behavior occurs in more than one use case. Similarly, alternative flows allow the introduction of optional or alternative behavior within a use case. These techniques should be used to their fullest before additional relationships between use cases are introduced. Many systems can be fully described using these techniques without the need to resort to any additional structuring of the use-case model.

Defining Relationships Between Use Cases

If most systems can be fully described using only use cases with relationships only to their actors, what would force us to add relationships between use cases, especially when we have already noted that most teams get into trouble when they try to use them? The simple answer is that two forces draw us toward using relationships. One force is commonality in behavior between two or more use cases, and the other is reducing complexity by isolating portions of use cases that may apply only in specific circumstances. When common behavior occurs, gathering it into a use case of its own can lead to improved readability and consistency of description. Similarly, if some behavior applies only in very specific contexts, separating that behavior into a use case of its own can make the rest of the use case easier to understand. The trick is knowing when to separate behavior into its own use case and when to leave well enough alone.

No matter what—and we cannot emphasize this enough—do not introduce relationships between use cases until you have at least a draft of the flow of events of the use cases. Outlining may seem sufficient, but it often lacks the detail necessary to see commonality (in the case of inclusion) or variation (in the case of extension). The only reason for introducing relationships is to deal with commonality and variations in the flows of events of the use cases; if you introduce them earlier, you are doing so without any real knowledge. Once you have at least drafted the use-case descriptions, commonality and variations will become obvious and you may safely proceed, provided that introducing the relationships will increase the understandability of the use-case descriptions. [1]

Using the Include Relationship

The include relationship provides the ability to extract common sections from two or more use-case descriptions and place them in a separate use case from which they can be referenced. The key point about this is that in order to use the include relationship, you must have the same descriptive text in at least two different use-case descriptions. This requires you to have actually written something. There are two critical mistakes that teams make that cause them to go awry with the include relationship. The first is that they introduce included use cases before they have written any descriptive text (working only with diagrams). The second is that they introduce use cases that are only included by one use case.

To understand how the include relationship can be used effectively, let’s consider two different use cases that share repeated sections.

Example

Use Case—Answer Customer Inquiries

Basic Flow

  1. The use case begins when the actor Customer calls the Customer Service Center Support Number.

  2. The system opens a customer service request (CSR) and logs the date and time of the call.

  3. The system then obtains the number of the phone from which the incoming call was placed.

  4. The system records this in the CSR log entry.

  5. The system then uses the phone number to determine whether there have been any prior calls placed from this number; if prior calls have been made, the system records references to the prior call information in the CSR and then routes the call to the next available Customer Service Representative and displays the CSR to them.

  6. The Customer Service Representative enters the Customer’s identification number.

  7. The system determines whether the Customer’s personal information is already on file.

  8. If it is, the system then uses the customer identification number to determine whether there have been any prior calls placed by this Customer; if prior calls have been made, the system records references to the prior call information in the CSR.

  9. If it is not, the system asks the Customer Service Representative to capture

    1. the Customer’s name (last name, first name, and middle initial)

    2. the mailing address (street address or post office box number, city, state or province, postal code, and the country)

    3. the phone number

    4. the hours during which the Customer can be contacted at that number

    5. an alternate contact phone number

    6. and the e-mail address

  10. When the state or province is entered, the system checks to see if the state or province is valid for country entered.

  11. The system also checks the postal code to see if it is valid for the country and province indicated.

  12. The system stores the customer information and allocates the Customer the next available customer identification number.

  13. The Customer Service Representative captures information about the preferred method of contact.

  14. The system adds the customer identification number to the CSR.

  15. The Customer Service Representative then captures the product number of the product the customer is using.

  16. The Customer Service Representative then captures, in textual form, the customer’s question.

  17. The system creates a new inquiry and stores the question.

[The remainder of use case is omitted for brevity and clarity.]

Use Case—Order Products

Basic Flow

  1. The use case begins when the actor Sales Representative selects to place an order.

  2. The system asks the Sales Representative to enter the customer’s customer identification number.

  3. If the customer is a new customer, the Sales Representative records

    1. the customer’s name (last name, first name, and middle initial)

    2. the mailing address (street address or post office box number, city, state or province, postal code, and the country)

    3. the phone number, the hours during which the customer can be contacted at that number

    4. an alternate contact phone number and the e-mail address

    5. When the state or province is entered, the system checks to see if the state or province is valid for country entered.

    6. The system also checks the postal code to see if it is valid for the country and province indicated.

    7. The Sales Representative records information about the preferred method of contact. The Sales Representative then records the “ship-to” information, if it is different from the customer’s billing address.

[The remainder of use case is omitted for brevity and clarity.]

From these two short use-case extracts, it is easy to see that there are some similarities in the text marked in italics. Perhaps there is an opportunity to record some of this information in a way that makes it easier to reuse. There are a couple of ways that we could do this.

First, we could define customer information in our glossary, recording the information that we need to capture about the customer. That will take away a lot of the common information, but we are still left with some common behavior that must be described. The include relationship enables us to separate this common text into a use case of its own, with references from the description in the including use cases to the included use case. A diagram showing the new use case and its relationships is presented in Figure 10-1.

Updated use cases and their relationships

Figure 10-1. Updated use cases and their relationships

In addition to being represented in the diagram, the include relationship manifests itself in the use-case descriptions. The following example shows the descriptions for all three use cases after we have extracted the common text into an included use case.

Example

Use Case—Answer Customer Inquiries

Basic Flow

  1. The use case begins when the actor Customer calls the Customer Service Center Support Number.

  2. The system opens a customer service request (CSR) and logs the date and time of the call.

  3. The system then obtains the number of the phone from which the incoming call was placed.

  4. The system records this in the CSR log entry.

  5. The system then uses the phone number to determine whether there have been any prior calls placed from this number.

  6. If prior calls have been made, the system records references to the prior call information in the CSR and then routes the call to the next available Customer Service Representative and displays the CSR to them.

  7. The Customer Service Representative enters the Customer’s identification number.

  8. The system determines whether the Customer’s personal information is already on file.

  9. If it is, the system then uses the customer identification number to determine whether there have been any prior calls placed by this Customer; if prior calls have been made, the system records references to the prior call information in the CSR.

  10. If it is not, include use case Add Customer Information so the Customer Service Representative can record information for this customer. [*]

  11. The system adds the customer identification number to the CSR.

  12. The Customer Service Representative then captures the product number of the product the customer is using.

[The remainder of use case is omitted for brevity and clarity.]

Use Case—Order Products

Basic Flow

  1. The use case begins when the actor Sales Representative selects to place an order.

  2. The system asks the Sales Representative to enter the customer’s customer identification number.

  3. If the customer is a new customer, include use case Add Customer Information so the Sales Representative can record information for this Customer.

  4. The Sales Representative then records the “ship-to” information, if it is different from the customer’s billing address.

[The remainder of use case is omitted for brevity and clarity.]

Use Case—Maintain Customer Information

Brief Description

This use case is included by other use cases. It is used to add customer information for new Customers (see glossary for full definition). Customer information may be entered or modified in any order.

Basic Flow

  1. The system prompts the user to enter the customer information.

  2. When adding or modifying customer information:

    1. When the state or province is entered or changed, the system checks to see if the state or province is valid for the country entered.

    2. When the postal code is entered or changed, the system checks to see if it is valid for the country and state or province indicated.

  3. The use case ends when the additions or changes to the customer information are saved, or the additions or changes are aborted.

Notice that by using an included use case, we have simplified the original use cases. We have also used the glossary to good effect, locating the definition of customer information there instead of cluttering our use cases with the information. Notice also that in creating the new included use case, we had to rewrite some of the descriptions in both the original use cases as well as in the new included use cases. In the original use cases, we removed the redundant description and inserted a reference to the included use case. In the included use case, we generalized the description so that it would be useable anywhere there is a need to add customer information.

An included use case should never be included by only one use case. If that happens, then it means that we have simply started to break down use cases into smaller use cases, with the result that we start to lose the thread of the use case. Do use techniques like the glossary or the domain model, or even appendices and reference documents to manage details, but do not use the include relationship to start breaking your use cases down into smaller use cases. Inclusion should only be used to manage common behavior.

One characteristic of an included use case is worth noting: It never has specific knowledge of the use cases that include it. The result is that included use cases are reuseable because they are not constrained by a particular con-text—they may be included by any use case without modification.

Common Errors Using the Include Relationship

The most common error is using the include relationship to perform a functional decomposition of the system. An example of this approach is treating the included use case as some sort of option in a menu, or a function. The error with using inclusion in this way is that the use case doing the including tends to become an empty shell—it often will have no real behavior of its own but becomes merely a dispatcher, calling other included use cases to do the real work. The included use cases, in turn, contain no common behavior and tend to be included by only one use case. The result is that none of the use cases, taken by themselves, provide any real value for a stakeholder of the system; they must be combined in some way to provide value. Since providing value is one of the key attributes of a use case, these fragments of use cases fail in at least one significant respect. A fragmented use-case model makes it very hard to see what the system does, and therefore it is very hard to tell if the system provides any value. The use cases, while perhaps technically correct, no longer convey a clear picture of what the system does and who it does it for. The more structured the model, the worse the problem.

Another common error is that behavior is added to the included use case outside the context of the use cases that include it. In the preceding example, it is very tempting to start to add behavior to cater to the update of existing customer information, the deletion of existing customers, or alternative and exceptional circumstances that could never occur within the context of the including use cases. Soon, the included use case takes on a life of its own as people continue to expand on its functionality without paying attention to the requirements of the original use cases where the need for the behavior was first identified. As well as causing uncontrolled and unintended scope creep, this often makes it impossible to identify the threads through the original use cases. When an include is used, it means that the whole of the included use case is part of the including use case and, therefore, that the entire included use case must be in place before any of the flows that include it.

Inclusion, when it is used at all, should clarify understanding, not impede it. If you find that use cases have been created for each function the system can perform, reorganize your use cases so that the value provided to the customer is evident in the names of the use case. Take each “functional” use case and turn it into a major subflow in the use-case description of the larger, value-oriented use case. This will reduce the total number of use cases, making the use-case model easier to understand at a glance, while still providing structure to the definition of the behavior of the system.

Using the Extend Relationship

The extend relationship is used in cases where optional or exceptional behavior is inserted into an existing use case. The original purpose of extension was to provide a mechanism for specifying options that could be added to an existing product, such as adding a feature for voice mail to an existing telephony switch. It is helpful to think of the extend relationship as being an add to relationship, since it always adds behavior to an existing use case. The defining characteristic of the extending use case is that it requires no changes in the use cases it extends. This means that the extended use case must be able to stand alone; it must be complete, without any need for extension in order to provide value.

Circumstances that may warrant extension include

  • Descriptions of features that are optional to the basic behavior of the system. Examples of this include behavior that may be optionally purchased, either from the original provider of the system or from third parties.

  • Descriptions of complex error- or exception-handling behavior that would otherwise obscure the primary behavior of the system. Examples of this are alternative flows that are of significant length, especially those that are longer than the main flow of the use case.

  • Customization of the requirements model for specific customer needs. Examples of this include alternative flows that specify how specific customers handle different conditions that occur within the same standard use case.

  • Scope and release management. Examples of this include behavior that will not be introduced until later releases.

Unlike the included use case, the extending use case is by necessity aware of the use case that it extends (henceforth called the base use case). It always extends a base use case at one or more extension points or under particular conditions. As a result, it is very unusual for a use case to extend more than one use case, since it is unlikely that more than one use case could have sufficiently common flows of events to enable effective extension. [2]

Conceptually, the mechanics of how an extending use case works is identical to that of an alternative flow. An extending use case explicitly inserts itself into the flows of the use case it is extending, just like an alternative flow, only the extending use case knows where in the base use case the behavior will be inserted. As a result, an extending use case will often begin life as an alternative flow.

Not every alternative flow can be turned into an extending use case. The rules for alternative flows are looser than those for extending use cases. Because alternative flows are part of the use case, they can exploit their knowledge of the use case’s state, preconditions, and other flow of events to end the use case or to resume the flow of the use case at extension points other than the one from which they assumed control. All extending use cases know about is the extension point at which they insert themselves into the flow of events of the use case that they extend. This enables the extended use case to be evolved without the need to worry about or consider the extending use cases.

The easiest way to understand extension is with a simple banking transaction processing example (see also Figure 10-2):

Basic Process Transactions use case diagram

Figure 10-2. Basic Process Transactions use case diagram

Example

Use Case—Process Transactions [*]

Brief Description

Processes transactions against the customer’s bank account.

Basic Flow

  1. The use case begins when the actor Cashier initiates transaction processing for a set of unprocessed transactions.

  2. The system orders the transactions so that all transactions for a particular account are grouped together, and within this grouping the deposit transactions are processed first to avoid unnecessary overdraft processing.

  3. For each account:

    {Determine Customer Account}

    1. The system determines the customer account to which the transaction is applied.

    2. For each transaction:

      {Apply Transaction}

      1. The system applies the transaction to the customer account. Deposit transactions increase the balance of the account; withdrawal transactions decrease the balance of the account.

        {Record Transaction}

      2. The system records the transaction information to a log to ensure a permanent record of the transaction.

      3. The system marks the transaction as completed.

        {Summarize Transactions}

      4. When all transactions for a particular account have been processed, the system creates a transaction summary for the account.

  4. When all transactions have been processed, the use case ends.

A1 Alternate Flow: Account Not Found

At {Determine Customer Account}, if the customer account is not found:

The system marks all transactions for the account as suspended transactions.

Processing continues for the next account at {Determine Customer Account}.

A2 Handle Account Overdrawn Without Overdraft Protection

At {Apply Transaction}, if the transaction causes an overdraft (the account balance goes negative) and the account has no overdraft protection:

The system applies the transaction and marks the transaction as “overdraft.”

The system applies an overdraft fee against the account.

Processing continues at {Record Transaction}.

A3 Handle Account Overdrawn with Overdraft Protection

At {Apply Transaction}, if the transaction causes an overdraft (the account balance goes negative) and the account has overdraft protection:

If the transaction does not cause the account to exceed the maximum overdraft allowance specified for the customer, the system apples the transaction to the customer account.

Processing continues at {Record Transaction}.

[Other alternative flows, including the one to handle exceeding the maximum overdraft allowance, are omitted for the sake of brevity and clarity.]

This sort of system has been around for years, since the days when nearly all applications were batch processing applications. Let’s assume that the company that provides this application has decided to update the application to use the latest technology, allowing the bank customer to be notified of the overdraft through a variety of electronic means, including e-mail, voice mail, or instant messages, according to preference. Because the Process Transactions use case is already complete in itself, the best way to describe this new behavior is to write a new use case that extends the existing use case (see also Figure 10-3).

A base use case, Process Transactions, being extended

Figure 10-3. A base use case, Process Transactions, being extended

Example

Use Case—Notify of Overdraft

Brief Description

This use case notifies the customer that the account has become overdrawn. This service is only available if the customer has purchased the overdraft notification service.

Extension

Extensions use case Process Transactions at {Summarize Transactions} if the customer has purchased the overdraft notification service and the set of completed transactions has caused the account to become overdrawn.

Basic Flow

  1. The system determines the customer’s preferred notification mechanism, as recorded in the customer profile.

  2. The system composes the overdraft notification, providing the transaction information, the date and time the transaction was processed, the account information, [*] the balance prior to the transaction, the balance subsequent to the transaction, and the amount of the overdraft fee, if any.

  3. The system transmits the overdraft notification message to the customer using the customer’s preferred notification mechanism.

  4. The use case ends. [†]

[For the sake of brevity and clarity the alternative flows, including the ones to handle there being no completed customer profile and communications failure, are omitted.]

This simple example illustrates the appropriate usage and benefits of extension: By enabling us to describe add-on features of the system in a simple way, separate from the base system itself, it simplifies the description of the system and makes it easier to understand. If an alternative flow is primarily providing behavior that is optional, meaning that the system could be delivered without it, it could be considered a candidate for becoming an extending use case. The decision to make it an extending use case should be based on these considerations:

  • Making it a separate use case makes it easier to manage from a versioning and configuration perspective.

  • The use cases will actually be owned and maintained by different people, perhaps because different expertise is required for the extension.

  • Separating it from the original use case makes both use cases easier to understand.

Extension could also be used to describe complex exception processing that would otherwise make the basic behavior system hard to understand.

The key thing to keep in mind about extension is that it always adds behavior to a use case. Because the base use case must remain intact and valuable on its own, the extension cannot modify the base use case. The basic behavior of the use case always remains intact.

Extension Points, Revisited

As introduced in Chapter 7, The Structure and Contents of a Use Case, extension points are named places in the flow of events where additional behavior can be inserted or attached. We introduced the notion in Chapter 7 that there are private extension points, visible only within the use case in which they occur, and public extension points, which are visible to extending use cases. Now that we have introduced extension, we should explore this statement further.

Extension points provide an easily readable way to refer to a particular location in the use-case description. This is useful because it removes the need to refer to step numbers (which tend to change) or to describe a synopsis of the use case to establish location (such as “the point after which the card has been validated but before the transaction proceeds”). The reason for introducing private and public scope to extension points is to reduce complexity. Since both alternative flows and extending use cases need to be inserted at a particular location within a use case, it is logical to have a single location reference mechanism to define this “insertion” or “extension” point. Within the flow of events extension points are shown in bold, enclosed in curly brackets. [3]

The difference between alternative flows and extending use cases is that alternative flows are contained within the same use case to which they refer. In addition, alternative flows are more numerous than extending use cases, and so it is typical for the extension points they use to be more numerous. Since most of these extension points are only meaningful for the alternative flows and not for extending use cases, we have made the distinction between these extension points, which are “private” in scope, and the extension points that may be referred to by extending use cases, which are “public” in scope.

Since public extension points represent a kind of “protocol” for the use case, special attention is paid to them when documenting the use case. Public extension points are enumerated in a separate section of the use-case description, as shown in the following example:

Example

Use Case—Browse Products and Place Orders

Public Extension Points

{Display Product Catalogue}

{Out of Stock}

{Process the Order}

{Order Processed}

Public extension points can be shown as part of the use case on use-case diagrams in a compartment named extension points, as shown in Figure 10-4. Declaring an extension point to be public indicates that it can be used by any extending use case to add behavior to the base use case. Not all extensions will be made public, nor should they be made public. Only the extension points that represent locations at which the use case can be extended should be made public.

Showing public extension points on a use-case diagram

Figure 10-4. Showing public extension points on a use-case diagram

In most cases, the public extension points section will simply enumerate the extension points that appear in the use-case description that should be made public. It is also possible for the public extension points section to declare extension points that do not appear in the use-case description. The reason for doing this is to prevent the use-case description from having to be modified in order for behavior to be added to it. This is essential in cases where use-case descriptions may be under strict configuration control and cannot be modified by the team adding the extending behavior. The format of the extension point declaration is

Note

{extension-point name}

at <some location in the use-case description>, or

before <some location in the use-case description>, or

after <some location in the use-case description>

The location description is informally described, such as “after the card is validated,” or “before currency is dispensed.”

Evaluating the Resulting Use-Case Model

The basic use cases of the system should reflect the essential value provided by the system. It should be possible to look at these use cases, excluding any included or extending use cases, and be able to understand what the system principally does for its stakeholders. Included and extending use cases should fill in more of the details, but they do not fundamentally change the principal value provided by the system. If you choose to use included or extending use cases, examine the model to make sure that their introduction has not changed the use-case model for the worse. If you remove all of the included and extending use cases from the model, the purpose of the system should still be clear. If the principle value of the system is still understandable without reference to any of the included or extending use cases, then you are probably on the right track.

Using Generalization Between Use Cases

The included use case gives us a way to share significant sections of common description among use cases, and the extending use case gives us the ability to add significant new behavior to an existing use case. Although these are powerful techniques, neither allows us to describe those situations where we wish to generalize or specialize a use case. The generalization relationship allows us to create generalized behavior descriptions that we can then specialize to meet particular needs.

So why would we want to do this?

The impetus to generalize use cases arises from the need to describe families of systems. Suppose we are developing a telecommunications service billing system that we would like to market to companies large and small. In order to meet the needs of these varied firms, we need a system that is very flexible. How can we express the variability of this kind of system without the flexibility of the system becoming so complex that the use cases become impossible to understand? The solution is generalization combined with extension to describe the optional features of the system. As before, it’s easier to understand this from an example.

Let’s consider our now-familiar ATM and assume that we work for a firm that produces software for ATMs. Let’s assume that we would like to expand our business into new areas, since the market for ATMs is growing more slowly than we would like. One morning, while on the way to work, we need some fuel in our automobile. While standing at the pump at the gas station, it occurs to us that the sequence of steps one goes through to purchase gas using a bank card is very similar to the sequence of steps that one goes through to withdraw cash from an ATM. The diagram of the use cases and actors is presented in Figure 10-5. Perhaps we can exploit this similarity to expand our ATM software business into new areas.

Use cases for Withdraw Cash and Fuel Vehicle

Figure 10-5. Use cases for Withdraw Cash and Fuel Vehicle

Once at the office, we start outlining the basic flow of events for the ATM Withdraw Cash use case and the gas pump Fuel Vehicle use case:

Withdraw Cash (ATM)

Fuel Vehicle (Fuel Pump)

Brief Description

Provides the customer with the ability to withdraw cash from a bank account using an automated teller machine.

Brief Description

Provides customers with the ability to fuel their vehicle, paying for the fuel directly from their bank account.

Basic Flow

  1. The Customer inserts a bank card into the ATM.

  2. The system reads the customer account information from the bank card.

  3. The system requests the Customer to enter the PIN.

  4. The Customer enters a PIN.

  5. The system verifies that the PIN entered is correct by comparing it to the PIN that was read from the bank card.

  6. The system contacts the Banking System to verify that the customer account information is valid.

  7. The system asks for an amount to withdraw. The Customer enters an amount.

  8. The system contacts the Banking System to verify that the Customer has sufficient funds to cover the withdrawal.

  9. The system checks to see if it has sufficient funds on hand to dispense the requested amount.

  10. The system dispenses the requested amount and records the amount dispensed.

  11. The Customer takes the cash.

  12. The system communicates that the transaction has been completed to the Banking System.

  13. The system logs the transaction, capturing the date and time of the transaction, the amount dispensed, and the account from which the funds were withdrawn.

  14. The use case ends.

Basic Flow

  1. The Customer inserts a bank card into the pump.

  2. The system reads the customer account information from the bank card.

    The system requests the Customer to enter the PIN.

  3. The Customer enters a PIN.

  4. The system verifies that the PIN entered is correct by comparing it to the PIN that was read from the bank card.

  5. The system contacts the Banking System to verify that the customer account information is valid.

  6. The system asks for the amount of fuel to be dispensed. The Customer enters an amount.

  7. The system contacts the Banking System to verify that the Customer has sufficient funds to cover the withdrawal.

  8. The system asks the Customer to lift the pump handle and begin dispensing fuel.

  9. The Customer dispenses the desired amount of fuel, or until the vehicle is full. When done, the Customer replaces the pump handle.

  10. The system records the amount dispensed.

  11. The system communicates that the transaction has been completed to the Banking System.

  12. The system logs the transaction, capturing the date and time of the transaction, the amount dispensed, and the account from which the funds were withdrawn.

  13. The use case ends.

If we look carefully at this example, the first six steps of the two use cases are virtually identical and steps 7–9 are very similar. The final steps in each use case are also very similar.

What if we wanted to define a framework for a general-purpose dispenser device, one that could dispense cash, or fuel, or theatre tickets, or even train tickets with only a few small changes? If we wanted to build such a system, we would want to have a set of use cases for the general-purpose dispenser, with specialized use cases for the specific customizations of this device. We can see from the example that neither extension nor inclusion could provide us with a good way to describe the general behavior. Inclusion of the various common parts of the use cases would leave us with very fragmented use cases. Extension does not provide a good way to express the variability in the framework, to expose the specific points at which the common behavior is specialized.

The solution is to create an abstract use case, Conduct Financial Transaction, that represents the dispenser framework, with specialized use cases Withdraw Cash and Fuel Vehicle. This is represented visually in Figure 10-6. The important parts of the use cases, however, are the use-case descriptions. These look as follows:

Use-case generalization and specialization represented visually

Figure 10-6. Use-case generalization and specialization represented visually

Examples

Conduct Transaction (abstract use case)

Brief Description

Provides the customer with the ability to receive goods from an automated dispenser, paying for them by an automated withdrawal from a bank account.

Basic Flow

  1. The actor Customer inserts a bank card into the dispenser machine.

  2. The system reads the customer account information from the bank card.

  3. The system requests the Customer to enter the PIN.

  4. The Customer enters a PIN.

  5. The system verifies that the PIN entered is correct by comparing it to the PIN that was read from the bank card.

  6. The system contacts the Banking System to verify that the customer account information is valid.

  7. The system asks for an amount of the transaction. The Customer enters an amount.

  8. The system contacts the Banking System to verify that the Customer has sufficient funds to cover the transaction.

    {The Customer Conducts the transaction}

  9. The system records the amount of the transaction.

  10. The system communicates that the transaction has been completed to the Banking System.

  11. The system logs the transaction, capturing the date and time of the transaction, the amount of the transaction, and the account from which the funds were withdrawn.

  12. The use case ends.

Withdraw Cash (concrete use case)

Brief Description

Specializes Conduct Transaction to enable a customer to withdraw cash from an Automated Teller Machine (ATM).

Basic Flow

At {The Customer Conducts the Transaction}:

  1. The system checks to see if it has sufficient funds on hand to dispense the requested amount.

  2. The system dispenses the requested amount of cash.

  3. The system asks the Customer to take the cash.

  4. The Customer takes the cash.

  5. The behavior described in use case Conduct Transaction resumes.

Fuel Vehicle (concrete use case)

Brief Description

Specializes Conduct Transaction to enable a customer to obtain fuel from a fuel pump by paying directly from a bank account.

Basic Flow

At {The Customer Conducts the Transaction}:

  1. The system asks the Customer to lift the pump handle and begin dispensing fuel.

  2. The Customer dispenses fuel up to the value of the amount entered, or until the tank is full.

  3. The Customer replaces the pump handle.

  4. The behavior described in use case Conduct Transaction resumes.

In cases where specialization is used, it is important to recognize that it is the specialized use cases that are actually performed. They reuse parts of the generalized use case. In a sense, specialization has the mechanics of an include, since it reuses description in another use case (in this case, the generalized use case), but the semantics of an extend, since it is the specialized use case that provides the additional behavior. When the specialized use case is performed, behavior from both the generalized and specialized use case is performed, as visualized in Figure 10-7.

Behavioral “flow of control” in specialized and generalized use cases

Figure 10-7. Behavioral “flow of control” in specialized and generalized use cases

Specialization makes it easy to see the common behavior and how and where it is specialized to provide different kinds of similar behavior. In addition, the resulting use cases become easier to read and understand. Specialization is a powerful technique for simplifying the description of similar behavior. Specialization, like extension, always adds behavior or overrides existing behavior. It utilizes the same extension point mechanism as extension. Unlike extension, specialization is used to refine the description of behavior. A generalized use case may be useable in its own right, but more probably it is abstract, meaning that it cannot be performed without being specialized. The value of specialization is that it simplifies complex descriptions.

A use case may be specialized at any number of extension points. The example shown shows specialization at only a single extension point to simplify the presentation. If we were to refine our example, we would find that further specialization would be required at a number of other points, such as printing the receipt, handling the card, and a number of other areas. As with extension, specialization only occurs at public extension points. At this point, it may sound like specialization and extension are the same things, since both add behavior to some existing use case. Although that much is true, they serve different purposes and work in different ways.

A single use case can be extended by more than one extending use case. The extended use case is the one that the actor starts and it must be “complete and meaningful” on its own, as there is a possibility that none of the extensions will be performed. When the extended use case is performed, the extending behavior is inserted into the flow of events when certain conditions occur. As a result, extensions affect the instances of the use case. Because multiple extensions can occur, the behavior of the use-case instance derives it behaviors from not only the base use-case but also some set of extending use cases.

Contrast this with specialization. In this case, it is the specialized use case that is started and not the base use case. The base use case, therefore, does not need to be “complete and meaningful”—in fact, it will have blanks in it that are to be completed by the specializations. When the specialized use case is performed, it follows only itself (some of which derives from its parent or par-ents). If more than one use case specializes a base use case, an instance of the use case follows only one of the specialized use cases. So, as you can see, extension and generalization are quite different.

Defining Relationships Between Actors

The only relationship between actors is generalization. Generalization is used to show similarity between actors. The main value in this is to show that some group of actors share common responsibilities or common characteristics. It is never used to reflect security permissions; security needs to be enforced by the system and therefore needs to be described in the use cases. Actors, by definition, are outside the system.

Useful characteristics to attach to actors include things that the testers will need to know about the actors, such as their expertise, the things that they need from the system, and the useability and response requirements the actors impose on the system. The actor generalization shown in Figure 10-8 illustrates that the Field Sales Representative and the Telesales Representative inherit the characteristics of the Sales Representative. This also means that they inherit the Sales Representative’s communicates relationships, with the use cases with which it interacts, and the set of user types it is associated with.

Actor generalization and specialization represented visually

Figure 10-8. Actor generalization and specialization represented visually

Sometimes, the use of actor generalization can simplify the use-case model by reducing the number of communicates relationships required, but usually it is of little or no use. The use of actor generalization is typically a symptom of the modelers confusing the actors with organizational roles and job titles (as discussed in Chapter 3, Establishing the Vision, and Chapter 4, Finding Actors and Use Cases). It is often a misguided attempt to model the organization’s communications, authority levels, and reporting hierarchies using actors. Remember that the actors only define roles with respect to the system that the users can take on, and nothing more.

There is no need for any other relationships between actors, as they do not communicate with one another. Some people find this strange—people who will play the actors will of course interact with one another in the organization in which the system exists. The point is that since these interactions do not directly involve the system, they are outside the scope of the system. Athough it is tempting to try to turn the system use-case model into a model of the business, that will only confuse everyone. As discussed in an earlier chapter, a system use-case model is completely different from a use-case model of the business, so in the system use-case model we ignore things that happen outside the system. This enables us to focus on understanding what the system does for its actors.

Summary

The relationships between use cases are problematic. Although powerful, they typically lead the inexperienced use-case modeler into dangerous ter-rain. Inappropriately applied, the include, extend, and generalization relationships lead to fragmented, overly structured models that resemble more complex designs than the simple descriptions of behavior that use-case models should be. When used correctly, the use-case relationships should simplify the use-case descriptions, not complicate them. The use-case relationships are summarized in Table 10-1.

It is not by accident that the examples we have presented have focused on use-case descriptions and not diagrams. The real value of the relationships comes not from their representation in use-case diagrams, but their effect on the use-case descriptions. As a result, use-case relationships should never, ever be introduced before fairly detailed descriptions have been written. Until descriptions have been written, there is not enough information present to justify the introduction of relationships. As we have stressed throughout this book, the use-case model is primarily a vehicle for facilitating communication and agreement among the stakeholders. Extending the communication metaphor, the use of use-case relationships can be compared to swearing: If used in moderation, and at the appropriate time, they can be very effective in communicating your message, but if overused, or used inappropriately, they will distract from the message, often putting people off so much that they ignore your message entirely. [4]

Table 10-1. Summary of Use-Case Relationships

Relationship

Graphical Representation

Meaning

Summary of Use-Case Relationships

include

<< include >>

Specifies that the source (including) use case explicitly incorporates the behavior of the target (included) use case at a location specified by the source use case.

Used to share behavior between use cases.

Summary of Use-Case Relationships

extend

<< extend >>

Specifies that the source (extending) use case extends the behavior of the target (extended) use case at a given extension point.

Used to add optional behavior to use cases without their knowledge.

Summary of Use-Case Relationships

generalization

 

Specifies that the source (specialized) use case specializes the target (generalized) use case.

Used to create general-purpose framework use cases that can be specialized to provide variations of the general behavior to cater to specific customizations of the system.



[1] Extension and Generalization were originally introduced by Ivar Jacobson. Inclusion came later, with the definition of UML 1.0.

[*] Note that in addition to the use-case name, we have added a brief explanation for the inclusion. This helps the reader to understand why the use case is being included.

[2] It is possible for a use case to extend a use case that is included by other use cases. One must be careful in doing this, lest the use cases become hard to understand because they are split into so many parts.

[*] This is also an example of how use cases can be used to describe batch processing.

[*] For the sake of simplifying the example, we won’t worry about the wisdom of transmitting account information over potentially unsecured media, although a real solution would have to contend with this issue.

[†] This indicates that the extending use case does not end the use case being extended. Extending use cases cannot end the use cases they extend. Remember that extending use cases must return to the extension point from which they took control.

[3] There are other ways of showing extension points, but this is the one we prefer and is therefore the one that we have used throughout this book.

[4] As they say to children who swear in the UK, “It’s not big or clever.”

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

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