38.16. Transactional States and the State Pattern
Transactional support issues can get complex, but to keep things simple for the presentto focus on the GoF State patternassume the following:
- Persistent objects can be inserted, deleted, or modified.
- Operating on a persistent object (for example, modifying it) does not cause an immediate database update; rather, an explicit commit operation must be performed.
In addition, the response to an operation depends on the transactional state of the object. As an example, responses may be as shown in the statechart of Figure 38.12.
Figure 38.12. Statechart for PersistentObject.
Ambler00b] is a good reference on a PersistentObject class and persistence layers, although the idea is older.
[7] Some issues with extending a PersistentObject class are discussed later. Whenever a domain object class extends a technical services class, it should be pause for reflection, as it mixes architectural concerns (persistence and application logic).
Figure 38.13. Persistent objects.
|
|
State Context/Problem An object's behavior is dependent on its state, and its methods contain case logic reflecting conditional state-dependent actions. Is there an alternative to conditional logic?Solution Create state classes for each state, implementing a common interface. Delegate state-dependent operations from the context object to its current state object. Ensure the context object always points to a state object reflecting its current state. |
Figure 38.14. Applying the State pattern.[10]
[View full size image]
[10] The Deleted class is omitted due to space constraints in the diagram.
State-dependent methods in PersistentObject delegate their execution to an associated state object. If the context object is referencing the OldDirtyState , then 1) the commit method will cause a database update, and 2) the context object will be reassigned to reference the OldCleanState . On the other hand, if the context object is referencing the OldCleanState , the inherited do-nothing commit method executes and does nothing (as to be expected, since the object is clean).Observe in Figure 38.14 that the state classes and their behavior correspond to the state chart of Figure 38.12. The State pattern is one mechanism to implement a state transition model in software.[8] It causes an object to transition to different states in response to events.
[8] There are others, including hard-coded conditional logic, state machine interpreters, and code generators driven by state tables.
As a performance comment, these state objects areironicallystateless (no attributes). Thus, there does not need to be multiple instances of a classeach is a singleton. Thousands of persistent objects can reference the same OldDirtyState instance, for example.