One of the most powerful features in the state machine workflow is recursive composition of states. Much of the flexibility in modeling that the state machine offers comes from the recursive composition feature.
In certain processes there are requirements where certain events can happen any time. For example in a purchase order process the purchase order can be canceled any time or the change event can happen only when the PO is in the opened state or the PO is in the approved state but not shipped. Modeling such events can become challenging. One option can be to model the same event in every state where the event can occur. But that is a lot of repetition of the same behavior. What we want is a behavior similar to what is provided in Object inheritance. We need to provide the common behavior in some base class and then have that behavior inherited in all the other derived classes.
Recursive composition offers a very elegant solution to this problem. In recursive composition model a state activity can contain other state activities. Any event handlers that are attached to the container state are inherited by the contained states. The state machine workflow root activity is also a state activity so if any event handlers are attached to the root state machine workflow then they are inherited by all the states within the state machine. If you look at it closely it is very similar to object inheritance. The behaviors to be inherited is the behavior in the event handlers.
So now to model the Cancel event in the PO example all we need to do is to simply attach the Cancel event handler at the root state machine activity. To model the Change event we need to create a State and include the Opened and the Approved state in it. Now we can attach the change event handler to the state the we have created.
Consider another example of an interactive voice response (IVR) application. In that application you need to create a menu system to which the end user will respond to over the phone. Now in it you can have options like 'At any time Press 9 to go to the main menu' or 'At any time press * to end the phone conversation'. You can now model these as events attached to the root state machine workflow. You do not have to provide for them in every state. In some cases you can have a certain set of sub-menu's grouped to provide functionality like 'press 8 to go back to the previous menu'. All these functions can now be performed very easily.
Another cool thing that is offered is that in some cases you can override the default behavior that you may have provided in the event handler of a container state. For example in the case of handling the 'Cancel' event in the PO process we simply added the 'Cancel' event handler at the root state machine level. Now let us say you want to override that behavior in the 'PO Approved' state. May be we want to handle the 'Cancel' differently when the PO is approved. We can add an event handler in the PO approved state to handle the 'Cancel' event and provide the special processing that we want to. Now while executing this state machine the Cancel behavior we have provided at the root level will be overridden by the 'Cancel' event handler in the PO Approved state. This is similar to overriding methods in Type inheritance.
The recursive composition model is similar to the State and Sub State concept in UML. There are certain restrictions in the State Machine Workflow though. In a State machine workflow you cannot transition to the state that contains other states. This is simply to avoid the ambiguity of the current executing state. If a transition to the container state is allowed then it is difficult to figure out which one of the states inside that state was the intended current state. It is of course possible if we have some sort of rules on the container states that can direct to the right state. This is similar to embedding a state machine inside another. We do not allow that yet and when we do that we can allow the flexibility to transition to the container state.
The designer also provides great support for recursive state composition. All you need to do is simply drop a state in another state. You can then drop event handler at the container state level. That's it. You do not have to do anything else for the inheritance to work.
Try this out in your process models. It is a great feature available and you will find that your process models are not only able to handle very complex requirements but are very elegant and easy to maintain.