State diagrams are a familiar technique to describe the behavior of a system. They describe all of the possible states that a particular object can get into and how the object's state changes as a result of events that reach the object. In most OO techniques, state diagrams are drawn for a single class to show the lifetime behavior of a single object.
There are many forms of state diagrams, each with slightly different semantics. The UML style is based on David Harel's (1987) statechart. Figure 8-1 shows a UML state diagram for an order in the order processing system I introduced earlier in the book. The diagram indicates the various states of an order.
Figure 8-1 shows a UML state diagram for an order in the order processing system I introduced earlier in the book. The diagram indicates the various states of an order.
We begin at the start point and show an initial transition into the Checking state. This transition is labeled "/get first item."
The syntax for a transition label has three parts, all of which are optional: Event [Guard] / Action. In this case, we have only the action "get first item." Once we perform that action, we enter the Checking state. This state has an activity associated with it, indicated by a label with the syntax do/activity. In this case, the activity is called "check item."
Note that I used the terms "action" for the transition and "activity" for the state. Although they are both processes, typically implemented by some method on Order, they are treated differently. Actions are associated with transitions and are considered to be processes that occur quickly and are not interruptible. Activities are associated with states and can take longer. An activity may be interrupted by some event. Note that the definition of "quickly" depends on the kind of system you are producing. Within a hard real-time system, "quickly" may mean within a few machine instructions; for regular information systems, "quickly" might mean less than a few seconds.
Note that the definition of "quickly" depends on the kind of system you are producing. Within a hard real-time system, "quickly" may mean within a few machine instructions; for regular information systems, "quickly" might mean less than a few seconds.
When a transition has no event within its label, it means that the transition occurs as soon as any activity associated with the given state is completed. In this case, that means as soon as we are done with the Checking. Three transitions come out of the Checking state. All three have only guards on their label. A guard is a logical condition that will return only "true" or "false." A guarded transition occurs only if the guard resolves to "true."
Only one transition can be taken out of a given state, so we intend the guards to be mutually exclusive for any event. in Figure 8-1, we address three conditions.
If we have not checked all items, we get the next item and return to the Checking state to check it.
If we have checked all items and they were all in stock, we transition to the Dispatching state.
If we have checked all items but not all of them were in stock, we transition to the Waiting state.
I'll look at the Waiting state first. There are no activities for this state, so the given order sits in this state, waiting for an event. Both transitions out of the Waiting state are labeled with the Item Received event. This means that the order waits until it detects this event. At that point, it evaluates the guards on the transitions and makes the appropriate transition, either to Dispatching or back to Waiting.
Within the Dispatching state, we have an activity that initiates a delivery. There is also a single, unguarded transition triggered by the Delivered event. This indicates that the transition will always occur when that event occurs. Note, however, that the transition does not occur when the activity completes; instead, once the "initiate delivery" activity is finished, the given order remains in the Dispatching state until the Delivered event occurs.
The final thing to address is a transition named "cancelled." We want to be able to cancel an order at any point before it is delivered. We could do this by drawing separate transitions from each of the Checking, Waiting, and Dispatching states. A useful alternative is to create a superstate of all three states and then draw a single transition from that. The substates simply inherit any transitions on the superstate.
Figure 8-2 and Figure 8-3 show how these approaches reflect the same system behavior.
Even with only three duplicated transitions, Figure 8-2 looks rather cluttered. Figure 8-3 makes the whole picture much clearer, and if changes are needed later, it is harder to forget the cancelled event.
In the current examples, I have shown an activity within a state, indicated by text in the form do/activity. You can also indicate other things within a state.
If a state responds to an event with an action that does not cause a transition, you can show this by putting text in the form eventName / actionName in the state box.
There are a couple of other types of events in addition to named events from the outside.
An event can be generated after a period of time. You indicate this with the keyword after. For instance, you might say after (20 minutes).
An event can be generated when a condition becomes true. You show this with the keyword when. For example, you could have when(temparature > 100 degrees).
There are also two special events, entry and exit. Any action that is marked as linked to the entry event is executed whenever the given state is entered via a transition. The action associated with the exit event is executed whenever the state is left via a transition. If you have a transition that goes back to the same state (this is called a self-transition) with an action, the exit action would be executed first, then the transition's action, and finally the entry action. If the state has an associated activity as well, that activity is executed after the entry action.