Recently I have been reverse engineering a state transition (officially a state machine but I prefer the term state transition model) to understand the complex life-cycle of our application’s central object.
I had seen a demo on model simulation but the focus was more on a generated model from source rather than a hand fashioned UML model. This post is a walk through on the process and hopefully some takeaways from what I’ve learned.
Understanding complex systems
I came into a project that is well down the road to completion but sorely lacking in any concrete documentation which was becoming a pain point for everyone – and particularly for me – the new analyst tasked with helping out.
One of my first tasks was to document some ‘light’ form of a state model to get an idea of all of the possible scenarios and break down some of the complexity. I’ve iterated through several versions (or styles) of the state model trying to provide a simpler view of states and state transitions but the model was just very complicated and the diagrams were too busy. Understanding it myself was hard enough and trying to validate each of the scenarios was proving far too time-consuming.
States and multiple sub-states – too many paths!
My main problem was due to having states and multiple sub-states being dependent on single transitions. For example, we had something like this
OBJECT (super state life-cycle)
-- sub item1 (sub state life-cycle) -- sub item2 (sub state life-cycle) -- shipping item (sub state life-cycle) -- other items (sub state life-cycle)
So for every transition, we could have movements of one or all of the sub-states, and depending on what states they were in, we could also have super-state changes.
[caption id="" align="aligncenter" width="628"] example of super-state / sub-state model I quickly threw together to serve as an example[/caption]
A threw together a quick example of what things (sort of!) looked like in our world – its a horribly rushed example but gets across the point.
Model simulation and simulation variables!
So I got to the point where I’d modelled enough states and sub-states that it was very difficult to validate the accuracy – so I decided to use a bit of smarts and try out model simulation.
I setup my workspace to get the simulation controls ready. It looks somewhat like this.
[caption id="attachment_818" align="aligncenter" width="716"] the simulation workspace configured to show variables, triggers and simulation console[/caption]
With this setup we can kick off model simulations to run through transitions, select the required ‘trigger’ to choose paths and even save triggers to define pre-defined scenarios to run through. Note: I’ll post a separate article on how to do each step in more detail.
All of this is nothing new? Well that's get into some simulation variables to track what's going on at each point.
First of all, I’ve run through a created scenario manually (interpreted in EA language) by manually selecting the triggers as they come up. You can then save these as a trigger set and select to signal the triggers automatically – now we can fly through our models after defining our criteria.
[caption id="" align="aligncenter" width="809"] model simulation in progress[/caption]
The above shows a simulation in action as it goes through the path I defined manually and you can see the trigger sequence waiting to be fired to progress the simulation further.
[caption id="" align="aligncenter" width="692"] showing the simulation console and 'waiting triggers' panel[/caption]
What I end up at the end is a list of states / decisions / elements that I have passed through in the console log and a list of triggers that were fired.
For me this wasn’t all that useful – just a flat list of states and sub-states at a single level wasn't;t really enough – plus there was more detail I wanted to capture that would make these even more useful.
Enter simulation variables
I stumbled on simulation variables when trawling through some EA help file about getting my simulations to work and instantly through of a use (more on that soon).
Given I am reverse engineering a model and not trying to do and model-driven development, I feel I can use simulation in this way but I certainly appreciate this is a hack job and not their intended purpose (sorry everyone!).
I added an operation to each state called ‘updateVars’ and added a behaviour to each to assign simple variable.
Protip: To avoid cluttering up your diagram with all your updateVars on each state element – hide the operations from the diagram in the diagram properties. Un-tick the ‘Operations’ box under Show Compartments.
[caption id="" align="aligncenter" width="585"] Protip - hide your operations from your state machine diagram to avoid clutter[/caption]
So now that I have added simulation variables to my model, I can see what the states and sub-states are at any given point in the model – either by pausing or setting simulation break points (another great feature!).
[caption id="" align="aligncenter" width="725"] example of paused simulation showing variables and waiting triggers[/caption]
Writing to simulation console
Although simulation variables were interesting they didn't really offer me much over what I had before – just a different way of viewing the same state/substate information. What I really wanted was to be able to use this concept to show other important things that are going on at certain steps.
Another cool feature Sparx have included here is being about to output to the simulation console so you can supplement the standard list of element names with your own text.
So at certain steps, I have UI actions or account deductions, that I wanted to bring into my model and highlight to my stakeholders where and when these were actually occurring. Strictly nothing to do with a state machine but I'm not here to win UML medals – just provide my stakeholders something they can understand!
So on one of the updateVars actions I can add another line like this:
[caption id="" align="aligncenter" width="519"] adding extra information to the console log[/caption]
The magic words here are Trace() which allow you to output a string to the console log. What does it look like in the simulation console? I'm glad you asked – it looks something like this.
[caption id="" align="aligncenter" width="558"] seeing the Trace() output onto the simulation console[/caption]
I ended up adding custom Trace() events for each state so I could better represent state /sub state movements and also record important events along the model.
Hopefully you followed along with me on this and I’ve had some interest regarding doing a screencast on the topic so please let me know in the comments if you’re interested and I’ll get one together.
This was an overview article to demonstrate the main features and I will come back and go through some of the steps I rushed through in more detail in the next post.