markb's profileWindows Live spacePhotosBlogListsMore ![]() | Help |
|
|
Hierarchial State Machine For CRUD
First of all the HSM pattern is very similiar to the Chain Of Responsibility pattern from the GO4 book. However it's more like the Tree Of Responsibility since there are multiple chains. Now what an HSM models, the problem it solves is the following. The HSM pattern models the context in terms of state in your software that you would have to reference in the branch logic of the event handling code in order to respond intelligently to requests and events. We frequently have to construct the context the software is in at a particular point in time in the event handling of our software. When it comes to managing CRUD ( Create, Read, Update Delete ) for an entity from data services, we need to know if the request times out, if the request immediately failed , if the entity is empty, if an entity was fetched successfully , if the entity is in the process of being saved, if the entity timed out being saved, if an error came back while the entity was being deleted; etc… , etc… etc… This is nothing new or profound - it is a solved problem in code. We write essentially ad-hoc code that examines state in various places to answer these questions in the software. Events can get complex since they arrive in unpredictable patterns, generally speaking event handling code is defensive in nature. The Chain Of Responsibility pattern is the following: Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. An HSM consists of a set of state handler delegates. Each state delegate is represented by a box in the diagram. If a box is nested inside of another box it means that it lives in the CONTEXT of the outer box. Everything that is true of the outer box is true of the inner box. This is known as behavioral inheritance. That is the core of the HSM system; you are inheriting behavior in the same manner that you inherit type in traditional class inheritance. Just like inheritance it is specialization in the sense that nested boxes only care about what is different from the outer box. So now you can write event handlers that are chained together, you can focus on special cases in the context of more generalized event handling. You can model what happened in the system in one cohesive location with a pattern that you can communicate to others. Since declarative programming is all the rage these days you have a DSL ( Domain Specific Language ) for event handling. What's more important is the topology of the HSM tells a story in terms of modelling the context that the software is in. HSM's have some interesting properties. There is always an active box ( state / event handler ) that all events and commands are directed at. If the state delegate consumes the event it does not bubble up the chain. In this way state delegates are only concerned with how to hande events and commands in a particular context. If no box/state delegate consumes the event it bubbles off the top unhandled. You can chose to take some action for certain events in this scenario depending on how important to your system an unhandled event of a certain type is. You can think of each box as some variable in your branch logic that allows you to remember where you were or what you should do that under the circumstances ( context ). You have a reactive system and you are forced to code to some correctness specification. An HSM allows you to do that – and to communicate your decisions to other programmers. The alternative is a code review of the event handling logic of your program. So I think of an HSM as modeling the branch logic of my event handling code. Each box as I mentioned is some variable somewhere that allows me to take the correct branch so I can reject deleting an address while it is being loaded. Or saving something that is not valid; or thinking I am creating something new when it was loaded from the server; or allowing someone to edit an address that had timed out when it was being fetched. This is a behavioral pattern. It's not structure ; and it's not workflow. It doesn't model what I am supposed to do next. This is one of the hardest distinctions to make with HSM's because workflow or the process an object goes through frequently mirrors what can be done to it. So try not to get confused ; always think of each box as a procession of variables in the branch logic of the event handler for a class. It's not supposed to model the lifetime of the class or the steps involved in creating a new object, or editing and then saving. However it looks like that since those are the variables I would be checking against that tell me "I'm editing an address that was successfully fetched; the address is invalid so it's not ok to be saved; I should not allow delete either since the spec says we don't allow delete while in the edit state; that the user has to cancel out of that state frirst then they can delete." Feel free to ask me about it. Next is to model a simple shipping form – as you can see the canonical HSM is a simple CRUD model. An exercise is to add the requirement that upon being fetched successfully from the server examine the timestamp of the last AVV and if it's older then spec item – XYZ – then revalidate the address. Move the address into the proper state so that it 'reacts' intelligently depending upon the outcome of the validation. Note that error's , timeouts, and the like can occur. I can post a solution ( I think ) to this if anyone is interested. TrackbacksThe trackback URL for this entry is: http://ekejma.spaces.live.com/blog/cns!8272788D0933F9E5!204.trak Weblogs that reference this entry
|
|
|