Chapter 6 presented the analysis and decomposition of systems into their object structure and relationships. The other pillar of object-oriented analysis is the specification of dynamic behavior. Behavior binds the structure of objects to their attributes and relationships so that objects can meet their responsibilities. Ultimately, an object's operations implement its behavior. There are means for constraining and controlling these primitive operations into permissible sequences. The most important of these is the finite state machine. The behavioral notations and semantics of the UML were introduced in Chapter 3; this chapter focuses on how to effectively apply these notations and semantics to solve our real-world problems. 7.1.1 Simple BehaviorWe define three types of behavior: simple, state, and continuous. The object with simple behavior performs services on request and keeps no memory of previous services. A simple object always responds to a given input in exactly the same way regardless of its history. Some examples of simple behaviors are
For example, returns the same value regardless of what value can call the COS() function with previously. In other cases, the distinction is not as clear. Is the search of a binary tree simple or state-driven? If the behavior changes due to previous input, then it cannot by definition be simple. If the binary tree provides methods like next() and previous(), then it must maintain an internal state between calls. If the tree only provides calls such as find(), then at least to its clients it exhibits stateless behavior. Activity diagrams provide token-flow semantics. That is, an activity is decomposed into subactivities, until at the bottom we find actions. Actions execute when they receive a control token from each of their predecessor activities. In the case of simple sequential actions within an activity, this is just a statement that an activity (or action) begins to execute when the activity (or action) that comes before it completes. In the case of concurrency, an activity (or action) can have multiple predecessors, and so must receive a control token from every one of its predecessors before it is allowed to execute. Figure 7-1 shows an activity diagram for computing net worth. The forks and joins show activities that may be allowed to execute in parallel. Token flow semantics are simple to explain in the figure:
Figure 7-1. Token-Flow Semantics7.1.2 State BehaviorThe second type of object behavior is called state, state-driven, or reactive. Our definition of a state is as follows:
Modeling an object as a finite state machine (FSM) attempts to reduce the behavioral complexity by making some simplifying assumption. Specifically, it assumes the following:
The set of all possible behaviors of an object is bounded by the set of operations defined on the object. An FSM adds constraints regarding when and under what conditions those operations will execute. 7.1.3 Continuous BehaviorThe third kind of object behavior is called continuous. Many objects show continuous behavior, including digital filters and PID[1] control loops. All that is required is that the current output depend on the previous history in a smooth way. An object with continuous behavior is one with an infinite, or at least unbounded, set of existence conditions. PID control systems, fuzzy sets, and neural networks all display continuous behavior.
The UML is very expressly a discrete modeling language, and provides no direct means for modeling continuous system behavior.[2] However, many kinds of continuous behavior can be defined using token flow semantics. This is normally done by expressing the algorithm as difference equations (derived from the differential equations). Thus, activity diagrams can be used to express behavior that is continuous in value but discrete in execution. A PID control loop, for example, implemented with a difference equation, is executed periodically, and the object uses attributes to remember the previous value(s) necessary for the computations. However, activity diagrams cannot, without extension, model behavior that is continuous in time, such as the continuously executing mixing of gases, or combustion of fuel. It is often sufficient to use a difference equation approach for the behavioral modeling, but not always.
It is even sometimes appropriate to mix state and continuous behavior. For example, different sets of trajectory differential equations may be used, depending on whether a spacecraft is undergoing launch, achieving orbit, in orbit, or cruising. The sets of equations used in this case depend on the state (in this case, phase of flight) of the trajectory object. This is accomplished by modeling the overall behavior of the object as a state machine; the set of difference or differential equations is modeled as a "do activity" within the states. As the object enters a new state, a different set of differential equations governs the execution of the activity within the state. Since the UML relies so heavily on finite state machines to represent discrete behavior, let's now explore what than means in more detail. |