Pravin Indurkar

Recursive Composition Of States : A way to inherit behaviors in State Machine Workflow

 

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.

Published Sunday, October 02, 2005 2:55 PM by pravini

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Wei Shi said:

"In a State machine workflow you cannot transition to the state that contains other states." means that, the root state can only be used for the definition of state?

hehe, Maybe I must try WWF beta so that i can understand it.
November 24, 2005 4:33 AM
 

J. Ambrose Little said:

So there seem to be a few issues with this. Can you have multiple inheritance (composition)? My impression is not, so it suffers from the same limitation on that front as does C# and VB.NET. What if you want some (but not all) states in one container to also inherit events from another container?

Second, (along similar lines), you will I suppose have to group these states together on the diagram or have the container state be huge?

Third, what do you call the container state? I realize you can't currently transition to that state directly, but it still shows up and is a thing that needs to be named. Something like ContainerState1?

While I think state composition is a convenient side effect of the WF2 architecture that addresses the simpler cases of sharing events/actions between states, it suffers from the common drawbacks of single inheritance and object hierarchy in general. We definitely need a mechanism to support sharing of actions, I just wonder if this approach is the most effective, both conceptually and practically.

I have similar concerns about the WF2 state machine in general in that it seems to be a brute force application of the state machine on top of the sequential workflow model. It keeps the ball small on the framework side, and maybe that's important enough to sacrifice intuitiveness and giving the state machine a full-fledged residency in WF2 instead of a derivative one based on "state activities." I haven't used WF2 enough yet to see just how easy it will be to overcome the initial obscurity.

So essentially what I'm suggesting is that maybe either making states and activity composition more primitive in the framework would make it both easier to conceptually grok state machine workflow in this framework as well as provide more flexibility in terms action (event) reuse. It's probably too late for such a suggestion to be taken seriously, but I thought I'd toss it out there just in case.

It's entirely possible that I'm just not seeing the bigger picture, and I'd be glad if you could enlighten me if that's the case.
November 29, 2005 4:11 PM
 

Howard Richards said:

I have tried this but the HandleExternalEvent does not fire for an EventDriven that applies to a whole workflow or for a composite state. Have submitted a bug on MSDN as well.
July 26, 2006 6:04 AM
 

WillSmith said:

We absolutely must have full behavior inheritance.  It is like taking away my object oriented programming language now and asking me to go back and program in Fortran.  Simply read the book:

Practical Statecharts in C/C++ by Miro Samek

It discusses why the having hierarchy is simply a neccessity.  It also shows a full working design.

Once you have done the full version of Statecharts, it will become the most usefull workflow for GUI's
in WF.

So the question is:  when is WF2 going to be released with this functionality.

Thanks.
August 29, 2006 12:39 PM
 

Rick O'Shay said:

Recursive State Composition has problems.  Create a state machine layout organized in a logical way. Now add some event handlers (abort operation for example) to several states. If you want to re-use an event hander the diagram has to organized according to shared events (e.g., what states handle to abort operation) which is not an appropriate layout.  It's far from an elegant solution and more like a bad hack. The elegant solution is to allow re-usable event handlers (stateless of course) to be dropped on to a state.

On another note,  handlers and their contents are currently scoped within a state. It is extremely irritating to have to concoct a new name for each node in each state. Anybody who sits down and creates a state machine will see that glaring hole immediately. What could be more natural than having nodes names within a state be scoped within that state? What language hasn't had that for 30 years?

November 30, 2007 10:47 AM
 

Rick O'Shay said:

Not that it matters but calling a container a "recursive composition state" seems needlessly lofty. If it was an actual state it might be justified. Anyway, I just removed the state container and its shared event handlers and re-implemented in each state. My diagram no longer has the unnatural and confusing layout imposed by the state container.  

So, here's how to solve the problem in a way that is truly elegant. Let's you have 30 states and 12 of them handle the same event type. Add the event handler to one, then simply drag and drop that handler on the remaining 11. Simple, obvious, logical. This actually works but there's an annoying problem. The designer renames the handler and its elements every time you drop a new copy. There's no reason for it because it clearly should be scoped by the containing state. Now you have to rename each one of them or keep the rather information-free names "handler1, hander2" and so on.

Imagine if you could not use a variable name more than one time across your application? So why have such a draconian requirement in the WF definition?

November 30, 2007 6:54 PM
 

Pravin Indurkar Recursive Composition Of States A way to inherit | Quick Diets said:

June 9, 2009 11:46 PM

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required
Submit

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker