12.1 Statechart Diagram Construction Techniques


12.1.1 Modeling Intention

When you come to build the statechart diagram for a class, take the perspective of an object and ask what you need to do to fulfill your destiny. (See [1] for an example of this type of thinking.)

A Shipment, for example, has to make something happen to cause itself to be packed, sent, and delivered to the customer. There's no point in just lying around waiting to be delivered. A Shipment needs to pack itself. Once packed, it needs to get picked up by the shipping company and then delivered to the Customer. The shipment drives itself through a sequence of states, as shown in Figure 12.1.

Figure 12.1. Shipment Lifecycle

graphics/12fig01.gif

Contrast the lifecycle of Figure 12.1 with an approach that models class behaviors as operations that "get" and "set" related attributes of the class, as shown in Figure 12.2. This model, in contrast to Figure 12.1, does not model a lifecycle, rather it relies on something else to take care of requesting to pack, contacting the shipping company, and so forth. This leads to a "spider" shape, with a central state that waits for requests and a set of legs that respond to each request.

Figure 12.2. Spider Lifecycle of Shipment

graphics/12fig02.gif

Moreover, this statechart diagram obscures key sequencing issues. There's nothing in the model to determine if a particular operation is valid or not. For example, if we wanted to make sure that we did not set the timeDelivered until the shipment was picked up, we'd need some logic to determine what the state of the object really is, possibly by testing attributes values. This is error-prone, especially if some logic is duplicated in different states.

Alternatively, we may add specific state attributes and then test them. The result in both cases is to encode the state in the logic of the procedures instead of making it explicit. This type of model quickly becomes unmanageable on screen and in concept.

The whole purpose of the lifecycle is to model intention: to capture the desire, on behalf of an object, to get something done.

12.1.2 Modeling Progression

Accumulating attribute values.

Many classes that model a request or task accumulate attribute values over time. For example, not all the attributes of the Shipment are set when the object is created.

This does not contradict the rule that every attribute must be meaningful for every object, because every attribute must be meaningful for any object at some time during the object's lifetime. In other words, it's perfectly all right for a Shipment to have a trackingNumber that's not yet specified until we get to the state where the shipment is picked up.

The Shipment statechart diagram in Figure 12.1 shows how different attributes of the Shipment are set in different states. Figure 12.3 shows how these attribute values accumulate over time.

Figure 12.3. Accumulating Attributes

graphics/12fig03.gif

Formally, these accumulating attributes have multiplicity 0..1, in contrast to the 1..1 multiplicity of attributes whose values are set at object creation.

Accumulating links.

This same notion also applies to links: Some conditional associations become meaningful only in certain states. For example, we might have an association between a Shipment and the Shipping Clerk who packed that Shipment, as shown in Figure 12.4.

Figure 12.4. Shipment and Clerk Association

graphics/12fig04.gif

We create the link in state 2: Waiting For Pickup, as shown in Figure 12.5.

Figure 12.5. Establishing the Association between Shipment and Shipping Clerk

graphics/12fig05.gif

12.1.3 Simultaneous Signals

Capture concurrency in the domain in the model. When a shipment is created we may simultaneously request a shipping clerk to pack the shipment and request a tracking number from the shipping company. The shipment can then receive two distinct signals: packed when the shipment is packed and trackingNumberAssigned when the shipping company assigns a tracking number. Figure 12.6 shows how the Shipment model accommodates this concurrency by having two distinct paths, accepting the two signals in either order.

Figure 12.6. Concurrent Signals

graphics/12fig06.gif

Since we request the packing and the tracking number simultaneously and the operations (outside of the domain) occur simultaneously, we can receive the packed and trackingNumberAssigned signals in either order. The Shipment statechart diagram must be capable of handling both sequences. It does this by having states and transitions such that either sequence of signals (packed, trackingNumberAssigned), or (trackingNumberAssigned, packed) cause the correct behavior of the state machine.

12.1.4 Distinct Signals

In the Order statechart diagram of Figure 9.10 on page 163, once a Charge is rejected (the paymentDeclined signal), there is no way to resubmit that charge. In practice, we would like to give the customer the opportunity to retry the charge. Perhaps the customer mistyped the number, or perhaps the link to the credit card company was down. Figure 12.7 shows a simple solution that incorporates a new transition from Payment Not Approved to Verifying Payment triggered by another checkOut signal.

Figure 12.7. Resubmitting a Charge Using CheckOut

graphics/12fig07.gif

While this solution is adequate, it has some problems. Do we really want the customer also to change the shipping information? Since the checkOut event carries both payment and shipping information, the updated model certainly allows this to happen.

If the intent is for the customer only to resubmit the payment information, then we should add a new signal, submitCharge. Figure 12.8 shows an updated statechart diagram with this new signal. Checking out an order for the first time carries both shipping and payment information. After the shipping information is set, the state's procedure generates submitCharge to self. The next state's procedure then processes the charge. Subsequent retries of the charge are signaled using submitCharge. By abstracting and using distinct signals, resubmitting the charge cannot have the unintended consequence of changing the shipping information.

Figure 12.8. Resubmitting a Charge Using a Separate submitCharge signal

graphics/12fig08.gif



Executable UML. A Foundation for Model-Driven Architecture
Executable UML: A Foundation for Model-Driven Architecture
ISBN: 0201748045
EAN: 2147483647
Year: 2001
Pages: 161

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net