"Extended state machines can apply the underlying formalism to much more complex problems than is practical without including extended state variables. For instance, suppose the behavior of the keyboard depends on the number of characters typed on it so far and that after, say, 1,000 keystrokes, the keyboard breaks down and enters the final state. To model this behavior in a state machine without memory, you would need to introduce 1,000 states (e.g., pressing a key in state stroke123 would lead to state stroke124, and so on), which is clearly an impractical proposition. Alternatively, you could construct an extended state machine with a key_count down-counter variable. The counter would be initialized to 1,000 and decremented by every keystroke without changing state. When the counter reached zero, the state machine would enter the final state.
In extended state machines, a change of a variable does not always imply a change of the qualitative aspects of the system behavior and therefore does not always lead to a change of state.
The obvious advantage of extended state machines is flexibility. For example, extending the lifespan of the �cheap keyboard� from 1,000 to 10,000 keystrokes would not complicate the extended state machine at all. The only modification required would be changing the initialization value of the key_count down-counter in the initial transition.
This flexibility of extended state machines comes with a price, however, because of the complex coupling between the �qualitative� and the �quantitative� aspects of the extended state. The coupling occurs through the guard conditions attached to transitions
Guard conditions (or simply guards) are Boolean expressions evaluated dynamically based on the value of extended state variables and event parameters. Guard conditions affect the behavior of a state machine by enabling actions or transitions only when they evaluate to TRUE and disabling them when they evaluate to FALSE.
The need for guards is the immediate consequence of adding memory extended state variables to the state machine formalism. Used sparingly, extended state variables and guards make up an incredibly powerful mechanism that can immensely simplify designs. But don�t let the fancy name (�guard�) and the concise UML notation fool you. When you actually code an extended state machine, the guards become the same IFs and ELSEs that you wanted to eliminate by using the state machine in the first place. Too many of them, and you�ll find yourself back in square one (�spaghetti code�), where the guards effectively take over handling of all the relevant conditions in the system.
Indeed, abuse of extended state variables and guards is the primary mechanism of architectural decay in designs based on state machines. Usually, in the day-to-day battle, it seems very tempting, especially to programmers new to state machine formalism, to add yet another extended state variable and yet another guard condition (another IF or an ELSE) rather than to factor out the related behavior into a new qualitative aspect of the system�the state. From experience in the trenches, the likelihood of such an architectural decay is directly proportional to the overhead (actual or perceived) involved in adding or removing states (which relates to the actual strategy used for implementing UML state machines.)
One of the main challenges in becoming an effective state machine designer is to develop a sense for which parts of the behavior should be captured as the �qualitative� aspects (the �state�) and which elements are better left as the �quantitative� aspects (extended state variables). In general, you should actively look for opportunities to capture the event history (what happened) as the �state� of the system, instead of storing this information in extended state variables. For example, a state machine representing the behavior of a pocket calculator might use an extended state variable DecimalFlag to remember that the user entered the decimal point to avoid entering multiple decimal points in the same number. However, a better solution is to observe that entering a decimal point really leads to a distinct state �entering_the_fractional_part_of_a_number,� in which the calculator ignores decimal points. This solution is superior for a number of reasons. The lesser reason is that it eliminates one extended state variable and the need to initialize and test it. The more important reason is that the state-based solution is more robust because the context information is used very locally (only in this particular state) and is discarded as soon as it becomes irrelevant. Once the number is correctly entered, it doesn�t really matter for the subsequent operation of the calculator whether that number had a decimal point. The state machine moves on to another state and automatically �forgets� the previous context. The DecimalFlag extended state variable, on the other hand, �lays around� well past the time the information becomes irrelevant (and perhaps outdated!). Worse, you must not forget to reset DecimalFlag before entering another number or the flag will incorrectly indicate that indeed the user once entered the decimal point, but perhaps this happened in the context of the previous number.
Capturing behavior as the quantitative �state� has its disadvantages and limitations, too. First, the state and transition topology in a state machine must be static and fixed at compile time, which can be too limiting and inflexible. Sure, you can easily devise �state machines� that would modify themselves at runtime (this is what often actually happens when you try to recode �spaghetti code� as a state machine). However, this is like writing self-modifying code, which indeed was done in the early days of programming but was quickly dismissed as a generally bad idea. Consequently, �state� can capture only static aspects of the behavior that are known a priori and are unlikely to change in the future.
For example, it�s fine to capture the entry of a decimal point in the calculator as a separate state �entering_the_fractional_part_of_a_number,� because a number can have only one fractional part, which is both known a priori and is not likely to change in the future. However, implementing the �cheap keyboard� without extended state variables and guard conditions would be practically impossible. This example points to the main weakness of the quantitative �state,� which simply cannot store too much information (such as the wide range of keystroke counts). Extended state variables and guards are thus a mechanism for adding extra runtime flexibility to state machines
Actions and Transitions
When an event instance is dispatched, the state machine responds by performing actions, such as changing a variable, performing I/O, invoking a function, generating another event instance, or changing to another state. Any parameter values associated with the current event are available to all actions directly caused by that event.
Switching from one state to another is called state transition, and the event that causes it is called the triggering event, or simply the trigger. In the keyboard example, if the keyboard is in the �default� state when the CapsLock key is pressed, the keyboard will enter the �caps_locked� state. However, if the keyboard is already in the �caps_locked� state, pressing CapsLock will cause a different transition�from the �caps_locked� to the �default� state. In both cases, pressing CapsLock is the triggering event.
In extended state machines, a transition can have a guard, which means that the transition can �fire� only if the guard evaluates to TRUE. A state can have many transitions in response to the same trigger, as long as they have nonoverlapping guards; however, this situation could create problems in the sequence of evaluation of the guards when the common trigger occurs. The UML specification intentionally does not stipulate any particular order; rather, UML puts the burden on the designer to devise guards in such a way that the order of their evaluation does not matter. Practically, this means that guard expressions should have no side effects, at least none that would alter evaluation of other guards having the same trigger"
So, yeah this is nice info for those that use state machines, but like most wikis it needs to be simplified.