UML 2 For Dummies
Sometimes there’s more than one way to reach a goal. When you find common purposes or goals in UML, you have an opportunity to use generalization—the object-oriented technique of specifying common features in a more general way to enable the reuse of objects. (For more about generalization, check out Chapter 2; for more about the UML notation for generalization, see Chapter 6.)
There are two common circumstances where you’ll find opportunities to generalize use cases:
-
Differing mechanisms for the same goal: If there’s more than one alternative technique or approach that the system uses to help the actors get their goals accomplished, they may share only a little implementation in common. If they meet the same goal, however, then the approaches will be still be sharing quite a bit: requirements, business rules, and data validations. With generalization, we can make this sharing explicit and save on duplications, by putting the common stuff in a single use case.
-
Differing agents for the same goal: If there is more than one actor trying to accomplish the same goal, you may be able to generalize the actors as we explain in the section above on generalizing actors in included use cases, However, you will find that often the actors have separate privileges, capabilities, or user interface. This is especially common when one actor acts as an agent or intermediary for the other. Generalizing the actors might still help, but now we want to explain how the use case works differently for each type of actor. Instead of generalizing the actors, generalize the use cases, placing in the generalized use case the common documentation, requirements, business rules, data validations, and perhaps implementation that they share. Using generalization will help you corral this common stuff and put it in its place (in a separate single use case).
Generalizing differing mechanisms
As technology evolves, your systems evolve as well. But it’s rare that you can completely eliminate legacy (pre-existing) solutions to long-standing needs. This can mean that at any one time, there are often several different ways to achieve the same goal.
Sometimes it’s not a question of retaining legacy approaches; you may just be hedging your bets with two different solutions to the same problem. Perhaps it’s because of uncertainly about what will become the dominant technology, or a desire to cater to diverse user populations with different preferences.
We show a typical example of such use-case generalization in Figure 10-4. The actor Potential Guest connects to the generalized use case Make Room Reservation. You place the common requirements, business rules, and even most of the flow description inside that use case. Then, in your lower-level (specialized) use cases, you have to document only the specific behavior required for their implementation mechanisms—that is, only the differences. In the figure, we show that we have to implement the same Make Room Reservation using modern HTTP Web technology, old-fashioned, VT100 technology, and IVR (Interactive Voice Response) pushbutton telephone technology.
You’ll find that when you generalize a use case in this manner, what you get is typically an abstract use case—one you can’t implement directly (because the details are missing) and that you can only put into action by implementing the specialized concrete use cases that specify the detailed mechanism. (UML indicates that a use case is abstract by italicizing its name and adding the {abstract} property tag.) There’s a discussion on abstract and concrete and how to indicate them in Chapter 6.
As part of the generalization notation, you can label the generalization (this label is called a discriminator) to clarify the basis or reasons for the generalization. We use the discriminator mechanism when we separate the implementation mechanisms in the diagram.
Warning If your use cases are only for identifying requirements and documentation, generalizing by mechanism can actually work against you. Instead, try putting the requirements, common business rules, and field validations in the generalized use case—don’t bother creating the specialized use cases at all (if you already created them, you can delete them). Unless you have to mention requirements that arise from the mechanism, specialized use cases may not offer much new to say. For many organizations, however, use cases serve purposes other than just gathering requirements—for example, they can help with scheduling and document organizing, or serve as a powerful explanatory tool. In such circumstances, generalizing by mechanism can still be valuable.
Generalizing differing agents
In the traditional model for service-oriented business, a customer contacts the business and requests some service. A worker—a cashier, library-circulation clerk, or hotel phone-reservation agent—performs the service for the customer. However, in our increasingly technological world, the customer may be able to interact directly with the system without using an intermediary (worker). Improving technology enables this trend toward disintermediation—in effect, losing the middleman—as a major thrust for Internet growth.
Your systems may have to support both direct (without an intermediary) and indirect (with an intermediary) usage—and traditionally you would construct a separate use case for each approach. Generalizing offers you an alternative. Figure 10-5 (for example) shows two different approaches to making hotel reservations—one direct (by Potential Guest over the Internet), and the other indirect (Potential Guest contacts a Reservation Clerk to do the work of making the reservation).
When you generalize your use cases, you also add complexity to the diagrams—but what you get back is thoroughness: You can diagram the generalized use cases, which map to the essential goals of the actors, as well as the different specialized variants on the themes.