|
Boost : |
From: Andreas Huber (spam2002_at_[hidden])
Date: 2002-09-08 11:22:56
Dave,
> >- Is it possible to "scope" the data appropriately?
> >
>
> Can you clarify what you mean by scope?
Sorry, but I have to give a somewhat lengthy explanation, please skip to the
end if you already know why I believe that state-local storage is important.
I think a part of an earlier post of mine gives a good introduction:
> [...] We've
> used Rhapsody for our past project (an ATM), where all guards and actions
> run in the same machine-global context (they are all non-static members
> functions of the same class). As a result of this, you could come across a
> state machine class having some 50+ data members, most of which were only
> used in a small part of the machine (and worse: some of them even
> reused!!!). I have always missed the ability to confine that data to the
> state machine part that actually used the data. [...]
By "to scope" (is this a verb in English?) I mean giving your data the exact
lifetime it should logically have. That is, why should data that is only
used in a small part of the machine continue to live when that part is left?
As demonstrated by the stop watch example in my proposal, state-local
storage allows you to confine data to where it's actually needed
(state-local storage is analogous to local variables in functional
decomposition):
1. As long as a stop watch is in the Stopped state (display showing
00:00:00), there is no need to have any data members around, because knowing
that we're in Stopped state is enough.
2. As soon as the stop watch is put into the Running state (by pressing the
Start button), we need to set the elapsedTime_ data member to 0 and record
the startTime_.
3. When the stop watch is paused, we need to subtract startTime_ from the
current time and add the result to elapsedTime_. Please note that startTime_
is not needed while we are in Paused state.
4. When the user presses Continue, startTime_ must be recorded again.
An so on... It turns out that elapsedTime_ is best made a data member of the
Active state (which has Running and Paused as nested states) and startTime_
is best made a data member of the Running state. The Stopped state and the
StopWatch state machine do not need any data members.
Agreed, in a tiny state machine as this one state-local storage is probably
an overkill because the traditional implementation with just one
machine-global context is just as easy to get right. However, when dealing
with complex machines I believe state-local storage becomes an important
tool to reduce complexity.
To finally answer your question I have to ask you back: Let's say in the
middle of a telephone call you need to store some intermediate data, which
is later used to calculate ... whatever (doesn't really matter). Where do
you store that data? In the (call-)context object? How do you ensure that
it's only used where it actually should be used? Again, this may smell like
overkill to people who have developed a particular state-machine from
scratch but for the new colleague at work who has to maintain that legacy it
could make all the difference.
Regards,
Andreas
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk