2.2. Use Case RelationshipsA use case describes the way your system behaves to meet a requirement. When filling out your use case descriptions, you will notice that there is some similarity between steps in different use cases. You may also find that some use cases work in several different modes or special cases. Finally, you may also find a use case with multiple flows throughout its execution, and it would be good to show those important optional cases on your use case diagrams. Wouldn't it be great if you could get rid of the repetition between use case descriptions and show important optional flows right on your use case diagrams? OK, so that was a loaded question. You can show reusable, optional, and even specialized use case behavior between use cases. 2.2.1. The <<include>> RelationshipSo far, you have seen that use cases typically work with actors to capture a requirement. Relationships between use cases are more about breaking your system's behavior into manageable chunks than adding anything new to your system. The purpose of use case relationships is to provide your system's designers with some architectural guidance so they can efficiently break down the system's concerns into manageable pieces within the detailed system design.
Take another look at the Create a new Blog Account use case description shown in Table 2-2. The description seems simple enough, but suppose another requirement is added to the Content Management System.
To capture Requirement A.2 a new use case needs to be added to the Content Management System, as shown in Figure 2-11. Now that we have added the new use case to our model, it's time to fill out a detailed use case description (shown in Table 2-3). See Table 2-1 if you need to refresh your memory about the meaning of each of the details within a use case description. Figure 2-11. A new requirement can often mean a new use case for the system, although it's not always a one-to-one mapping
The first thing to notice is that we have some redundancy between the two use case descriptions (Tables 2-2 and 2-3). Both Create a new Blog Account and Create a new Personal Wiki need to check the applicant's credentials. Currently, this behavior is simply repeated between the two use case descriptions. This repetitive behavior shared between two use cases is best separated and captured within a totally new use case. This new use case can then be reused by the Create a new Blog Account and Create a new Personal Wiki use cases using the <<include>> relationship (as shown in Figure 2-12). Figure 2-12. The <<include>> relationship supports reuse between use casesThe <<include>> relationship declares that the use case at the head of the dotted arrow completely reuses all of the steps from the use case being included. In Figure 2-12, the Create a new Blog Account and Create a new Personal Wiki completely reuse all of the steps declared in the Check Identity use case. You can also see in Figure 2-12 that the Check Identity use case is not directly connected to the Administrator actor; it picks this connection up from the use cases that include it. However, the connection to the Author Credentials Database is now solely owned by the Check Identity use case. A benefit of this change is that it emphasizes that the Check Identity use case is the only one that relies directly on a connection to the Author Contact Details Database actor. To show the <<include>> relationship in your use case descriptions, you need to remove the redundant steps from the Create a new Blog Account and Create new Personal Wiki use case descriptions and instead use the Included Cases field and include::<use case name> syntax to indicate the use case where the reused steps reside, as shown in Tables 2-4 and 2-5.
Now you can create a use case description for the reusable steps within the Check Identity use case, as shown in Table 2-6.
Why bother with all this hassle with reuse between use cases? Why not just have two use cases and maintain the similar steps separately? All this reuse has two important benefits:
2.2.2. Special CasesSometimes you'll come across a use case whose behavior, when you start to analyze it more carefully, can be applied to several different cases, but with small changes. Unlike the <<include>> relationship, which allows you to reuse a small subset of behavior, this is applying a use case with small changes for a collection of specific situations. In object-oriented terms, you potentially have a number of specialized cases of a generalized use case. Let's take a look at an example. Currently, the Content Management System contains a single Create a new Blog Account use case that describes the steps required to create an account. But what if the CMS supports several different types of blog accounts, and the steps required to create each of these accounts differs ever so slightly from the original use case? You want to describe the general behavior for creating a blog accountcaptured in the Create a new Blog Account use caseand then define specialized use cases in which the account being created is a specific type, such as a regular account with one blog or an editorial account that can make changes to entries in a set of blogs. This is where use case generalization comes in. A more common way of referring to generalization is using the term inheritance Figure 2-13. Two types of blog account, regular and editorial, can be created by the Management SystemTaking a closer look at the Create a new Editorial Blog Account specialized use case description, you can see how most of the behavior from the more general Create a new Blog Account use case is reused. Only the details that are specific to creating a new editorial account need to be added (see Table 2-7).
Use case inheritance is a powerful way of reusing a use case so that you only have to specify the extra steps that are needed in the more specific use cases. See Chapter 5 for more information on inheritance between classes. But be carefulby using inheritance, you are effectively saying that every step in the general use case must occur in the specialized use cases. Also, every relationship that the general use case has with external actors or use cases, as shown with the <<include>> relationship between Create a new Blog Account and Check Identity, must also make sense in the more specialized use cases, such as Create a new Editorial Blog Account. If you really don't want your more specific use case to do everything that the general use case describes, then don't use generalization. Instead, you might want to consider using either the <<include>> relationship shown in the previous section or the <<extend>> relationship coming up in the next section. 2.2.3. The <<extend>> RelationshipAny explanation of the <<extend>> stereotype should be preceded by a warning that it is the most heavily debated type of use case relationship. Almost nothing is less understood or harder to accurately communicate within the UML modeling community than the <<extend>> use case relationship, and this presents a bit of a problem when you are trying to learn about it. Figure 2-14 shows you how <<extend>> works; take a look, and then let's dive into some UML concept and theory. Figure 2-14. The <<extend>> use case relationship looks a bit like the <<include>> relationship, but that's where the similarities endAt first glanceparticularly if you are a Java programmer<<extend>> seems very similar to inheritance between classes. In Java, a class can extend from a base class. Similarly, in C++ and C#, you can declare inheritance between classes, and you would often say that a class extends another class. In both these cases, the extend relationship between classes means inheritance. So, for a programmer, it follows that <<extend>> should mean something like inheritance, right? Alarm bells should definitely be going off now. You already saw in the previous section how use cases declare inheritance using a generalization arrow, so why would you need yet another type of arrow with an <<extend>> stereotype? Does the generalization arrow mean the same thing as the <<extend>> stereotype? Unfortunately, the <<extend>> stereotype has very little in common with inheritance, and so the two definitely do not mean the same thing. The designers of UML 2.0 took a very different view as to the meaning of <<extend>> between use cases. They wanted a means for you to show that a use case might completely reuse another use case's behavior, similar to the <<include>> relationship, but that this reuse was optional and dependent either on a runtime or system implementation decision. From the CMS example, the Create a new Blog Account use case might want to record that a new author applied for an account and was rejected, adding this information to the author's application history. Extra steps can be added to the Create a new Blog Account use case's description to show this optional behavior, as shown in Step 4.3 in Table 2-8.
The same behavior captured in Step 4.3 would also be useful if the customer was refused an account for some reason during the Create a new Personal Wiki use case's execution. According to the requirements, this reusable behavior is optional in both cases; you don't want to record a rejection if the application for a blog account or a personal Wiki was accepted. The <<extend>> relationship is ideal in this sort of reuse situation, as shown in Figure 2-15. Figure 2-15. The <<extend>> relationship comes into play to show that both the "Create a new Personal Wiki" and "Create a new Blog Account" use cases might occasionally share the application rejection recording behaviorThe new Record Application Failure use case, as the name implies, captures all of the behavior associated with recording an author's application failure whether it be for a personal Wiki or for a specific type of blog account. Using the <<extend>> relationship, the Record Application Failure use case's behavior is optionally reused by the Create a new Blog Account and Create a new Personal Wiki use cases if an application is rejected. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Friday, October 30, 2009
Section 2.2. Use Case Relationships
How to Make Dialogs
< Day Day Up > |
How to Make DialogsSeveral classes support dialogs�windows that are more limited than frames. To create simple, standard dialogs, you use the JOptionPane class.[31] The ProgressMonitor class can put up a dialog that shows the progress of an operation.[32] Two other classes, JColorChooser and JFileChooser, also supply standard dialogs.[33] To bring up a print dialog, you use the Printing API.[34] To create custom dialogs, use the JDialog[35] class directly.
The code for simple dialogs can be minimal. Figure 11, for example, shows an informational dialog. Figure 11. A simple dialog.Here's the code that creates and shows the dialog:
An Overview of DialogsEvery dialog is dependent on a frame. When the frame is destroyed, so are its dialogs. When the frame is iconified, its dialogs disappear from the screen. When the frame is deiconified, its dialogs return to the screen. The AWT automatically provides this behavior. A dialog can be modal. When a modal dialog is visible, it blocks user input to all other windows in the program. The dialogs that JOptionPane provides are modal. To create a nonmodal dialog, you must use the JDialog class directly. The JDialog class is a subclass of the AWT java.awt.Dialog class. It adds to Dialog a root pane and support for a default close operation. These are the same features that JFrame has, and using JDialog directly is very similar to using JFrame directly. If you're going to use JDialog directly, then you should understand the material in Using Top-Level Containers (page 46) in Chapter 3 and How to Make Frames (Main Windows) (page 236) later in this chapter, especially Responding to Window-Closing Events (page 240). Even when you use JOptionPane to implement a dialog, you're still using a JDialog behind the scenes. The reason is that JOptionPane is simply a container that can automatically create a JDialog and add itself to the JDialog's content pane. The DialogDemo ExampleFigure 12 is a picture of an application that displays dialogs. Figure 12. The DialogDemo application.Try This:
JOptionPane FeaturesUsing JOptionPane, you can create and customize several different kinds of dialogs. JOptionPane provides support for laying out standard dialogs, providing icons, specifying the dialog's title and text, and customizing the button text. Other features allow you to customize the components the dialog displays and specify where the dialog should appear onscreen. You can even specify that an option pane put itself into an internal frame (JInternalFrame) instead of a JDialog. Note: When you create a JOptionPane, look-and-feel-specific code adds components to it and determines their layout. JOptionPane's icon support lets you easily specify which icon the dialog displays. You can use a custom icon, no icon at all, or any one of four standard JOptionPane icons (question, information, warning, and error). Each look and feel has its own versions of the four standard icons. Figure 13 shows the icons used in the Java look and feel. Figure 13. Icons provided by JOptionPane (Java look and feel shown).Creating and Showing Simple DialogsMost simple modal dialogs you create and show using one of JOptionPane's showXxx- Dialog methods. If your dialog should be an internal frame, add Internal after show�for example, showMessageDialog changes to showInternalMessageDialog. If you need to control the dialog's window-closing behavior or if the dialog isn't modal, you should directly instantiate JOptionPane and add it to a JDialog instance. Then invoke setVisible(true) on the JDialog to make it appear. The two most useful showXxxDialog methods are showMessageDialog and showOption-Dialog. The showMessageDialog method displays a simple, one-button dialog. The show-OptionDialog method displays a customized dialog that can display a variety of buttons with customized button text and can contain a standard text message or a collection of components. The other two showXxxDialog methods are used less often. The showConfirmDialog method asks the user to confirm something, but has the disadvantage of having standard button text (Yes/No or the localized equivalent, for example) rather than button text customized to the user's situation (Start/Cancel, for example). A fourth method, showInputDialog, is designed to display a modal dialog that gets a string from the user, using either a text field or an uneditable combo box. The following are some examples, taken from DialogDemo.java, of using showMessageDialog, showOptionDialog, and the JOptionPane constructor. For more example code, see DialogDemo.java and the other programs listed in Examples That Use Dialogs (page 199) later in this chapter. showMessageDialogDisplays a modal dialog with one button, which is labeled OK (or the localized equivalent). You can easily specify the message, icon, and title the dialog displays. Table 12 shows some examples.
showOptionDialogDisplays a modal dialog with the specified buttons, icons, message, title, and so on. With this method, you can change the text that appears on the buttons of standard dialogs and perform many other kinds of customization. (See Table 13.)
JOptionPane (constructor)Creates a JOptionPane with the specified buttons, icons, message, title, and so on. You then have to add the option pane to a JDialog, register a property-change listener on the option pane, and show the dialog. (See Table 14.) See Stopping Automatic Dialog Closing (page 195) for details.
The arguments to all of the showXxxDialog methods and JOptionPane constructors are standardized, though the number of arguments for each method and constructor varies. The following list describes each argument. To look at the complete list of arguments for a particular method, see The Dialog API (page 196). Component parentComponentAlways the first argument to each showXxxDialog method, it must be a frame, a component inside a frame, or null. If you specify a frame, the dialog will appear over its center and depend on it. If you specify a component inside a frame, the dialog will appear over the center of that component and depend on that component's frame. If you specify null, the look and feel picks an appropriate position for the dialog�generally the center of the screen�and the dialog doesn't depend on any visible frame. The JOptionPane constructors don't include this argument. Instead, you specify the parent frame when you create the JDialog that contains the JOptionPane and use the JDialog setLocationRelativeTo method to set the dialog's position. Object messageA required argument, this specifies what the dialog should display in its main area. Generally, you specify a string, which results in the dialog displaying a label with the specified text. You can split the message over several lines by putting newline (\n) characters inside the message string. For example:
String titleSpecifies the title of the dialog. int optionTypeSpecifies the buttons that appear at the bottom of the dialog. Choose from one of the following standard sets: DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION, OK_CANCEL_OPTION. int messageTypeDetermines the icon displayed in the dialog. Choose from the following values: PLAIN_MESSAGE (no icon), ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE. Icon iconThe icon to display in the dialog. Object[] optionsFurther specifies the option buttons to appear at the bottom of the dialog. Generally, you specify an array of strings for the buttons. See Customizing Button Text (page 194) for more information. Object initialValueSpecifies the default value to be selected. You can either let the default icon be used or specify the icon using the message type or icon argument. By default, a dialog created with showMessageDialog displays the information icon, and a dialog created with showConfirmDialog or showInputDialog displays the question icon. An option pane created with a JOptionPane constructor displays no icon by default. To specify that the dialog display a standard icon or no icon, specify the message type. To specify a custom icon, use the icon argument. The icon argument takes precedence over the message type; as long as the icon argument has a non-null value, the dialog displays the specified icon. Customizing Button TextWhen you use JOptionPane to create a dialog, you can choose either to use the standard button text (which might vary by look and feel) or to specify different text. The code shown in Table 15, taken from DialogDemo.java, creates two Yes/No dialogs. The first is implemented with showConfirmDialog, which uses the look-and-feel wording for the two buttons. The second uses showOptionDialog so that it can customize the wording. With the exception of wording changes, the dialogs are identical.
Getting the User's Input from a DialogAs the previous code snippets in Table 15 show, the showMessageDialog, showConfirm-Dialog, and showOptionDialog methods return an integer indicating the user's choice. The values for this integer are YES_OPTION, NO_OPTION, CANCEL_OPTION, OK_OPTION, and CLOSED_OPTION. Except for CLOSED_OPTION, each option corresponds to the button the user presses. CLOSED_OPTION indicates that the user is closing the dialog window explicitly rather than by choosing a button inside the option pane. Even if you change the strings that the standard dialog buttons display, the return value is still one of the predefined integers. For example, a YES_NO_OPTION dialog always returns one of the following values: YES_OPTION, NO_OPTION, or CLOSED_OPTION. If you're designing a custom dialog, on the other hand, you need to design its API so that you can query the dialog about what the user chose. For example, the dialog implemented in CustomDialog.java[37] has a getValidatedText method that returns the text the user entered.
Stopping Automatic Dialog ClosingBy default, when the user clicks a JOptionPane-created button, the dialog closes. But what if you want to check the user's answer before closing the dialog? In this case, you must implement your own property-change listener so that when the user clicks a button the dialog doesn't automatically close. DialogDemo contains two dialogs that implement a property-change listener. One of these is a custom modal dialog, implemented in CustomDialog, that uses JOptionPane both to get the standard icon and to get layout assistance. The other dialog, whose code is below, uses a standard Yes/No JOptionPane. Though this dialog is useless as written, its code is simple enough that you can use it as a template for more complex dialogs. Besides setting the property-change listener, the following code also calls JDialog's set-DefaultCloseOperation method and implements a window listener that handles the window close attempt properly. If you don't care to be notified when the user closes the window explicitly, ignore the bold code.
The Dialog APITables 16 through 18 list the commonly used JOptionPane[38] and JDialog[39] constructors and methods. Other methods you're likely to call are defined by the Dialog, Window, and Component classes and include pack, setSize, and setVisible.
Examples That Use DialogsThe following table lists examples that use JOptionPane or JDialog. To find other examples that use dialogs, see these sections: Examples That Monitor Progress (page 310), Examples That Use Color Choosers (page 175), and Examples That Use File Choosers (page 220).
|
< Day Day Up > |
Calling Multiple Controllers and Views
| [ Team LiB ] |
Calling Multiple Controllers and ViewsOne of the things you will notice in the controller servlet is that it has direct knowledge of the JSP that is handling the view�the name of the view that the JSP is coded in. You should strive to break such dependencies whenever you can. What happens if you want to do things exactly the same way in the controller but display a different view of the data? The controller should be concerned with sending information to the model, and the view should be concerned with displaying the output. The only thing that ties the controller to the view at the moment is the fact that the controller contains the logic to forward the request on to the view. The way to completely separate the controller from the view is with a dispatcher servlet. A dispatcher performs the crucial transition between the controller and the view. Instead of invoking a controller directly, you call the dispatcher and tell it which controller you want to call and which view to display. That way, the controller doesn't have any specific view hardwired into its code. Likewise, the dispatcher doesn't have a view hardwired in, either. Don't Confuse This Dispatcher with RequestDispatcher
You can even have the dispatcher call multiple controllers before invoking a view. That way, you can break your business logic down into finer-grained pieces. When the client sends a request to the server, it may invoke several controllers to update various portions of the model before displaying the view. Listing 20.4 shows the dispatcher servlet. In this example, you use parameters (form variables) named controller to pass the controllers. The pathname for the default view is passed in the view parameter, whereas the pathname for the error-handler view is passed in the errorView parameter. Listing 20.4 Source Code for DispatcherServlet.java
To use this dispatcher with the ControllerServlet, you need to strip a few things out of the controller. You no longer need to include the calls to gotoPage because the dispatcher is handling that. Also, rather than have it call the error page, make the controller throw a ServletException with the reason for the error. Listing 20.5 gives the source for the modified ControllerServlet. Listing 20.5 Source Code for ControllerServlet2.java
You don't need to change anything in the ShowPeople.jsp page to make it work with the dispatcher. The only other thing you need to do is modify the initial HTML form. It now needs to pass parameters to the dispatcher to tell it which controller and view to use. You can insert the information as hidden form variables so that it is automatically passed when the user submits the form. Listing 20.6 shows the modified HTML form. Listing 20.6 Source Code for PeopleQuery2.html
|
| [ Team LiB ] |
Overview
| ||||
| ||||
|
|
|
| valign="top" bgcolor="#FFFFFF"> | ||||
Section 9.6. A Participant's State-Line
9.6. A Participant's State-LineNow that you have added time to the timing diagram (fancy that!), you can show what state a participant is in at any given time. If you take a look back at Figure 9-6 and Figure 9-7, you can already see how participant's current state is indicated: with a horizontal line that is called the state-line. At any given time in the interaction, a participant's state-line is aligned with one of the participant's states (see Figure 9-9). Figure 9-9. In this example, p1:Participant's state-line indicates that it is in State1 for 1 unit of time, State2 for three units of time, and State3 for roughly five units of time (before returning to State1 at the end of the interaction)Figure 9-10 shows how the Create a new Regular Blog Account timing diagram is updated to show the state of each participant at a given time during the interaction.
That's all there is to showing that a participant is in a specific state at a given time. Now it's time to look at why a participant changes states in the first place, which leads us neatly to events and messages. Figure 9-10. Each of the participants needs to have a corresponding state-line to indicate their state at any given point in time |
Workshop
| [ Team LiB ] |
WorkshopThe Workshop is designed to help you review what you have learned and help you further increase your understanding of the material covered in this hour. Quiz
Answers
Activities
|
| [ Team LiB ] |