考虑一个简单的StateMachine。
下面是一段由C++代码生成的片段。BoUML 从它。
// to manage the event create
void Sample::Sample_State::State1_State::create(Sample & stm) {
_doentry(stm);
}
// perform the 'entry behavior'
void Sample::Sample_State::State1_State::_doentry(Sample & stm) {
stm.enter_state1();
}
// perform the 'exit behavior'
void Sample::Sample_State::State1_State::_doexit(Sample & stm) {
stm.exit_state1();
}
// perform the 'do activity'
void Sample::Sample_State::State1_State::_do(Sample & stm) {
stm.do_state1();
}
// to manage the event exit_state1
void Sample::Sample_State::State1_State::exit_state1(Sample & stm) {
_do(stm);
{
stm._sample_state._state1_state._doexit(stm);
stm._set_currentState(stm._sample_state);
stm._final();
}
}
注意: _do(stm)
所谓 Sample::Sample_State::State1_State::exit_state1(Sample & stm)
即从状态1退出时,就在调用退出行为 stm._sample_state._state1_state._doexit(stm);
UML规范 告诉我们。
14.2.3.4.3状态进入、退出和doActivity Behaviors。
. . .
一个状态还可以有一个关联的 doActivity 行为。该行为在进入状态时开始执行(但仅在状态进入行为完成后),并与可能与该状态相关联的任何其他行为同时执行,直到。
- 它完成(在这种情况下,会产生一个完成事件)或
- 状态被退出,在这种情况下,doActivity 行为的执行被中止。
状态的 doActivity Behavior 的执行不受该状态的内部转换的触发影响。
是不是更符合UML的规范,在这个状态下调用 _do(stm)
从 Sample::Sample_State::State1_State::create()
,紧接着 _doentry(stm);
?
其实这是最糟糕的,我把管理的对象换成了 做人 之间的进入和退出情况。考虑到状态机(从状态到自身的转换是内部的) 。
和主
int main()
{
MM mm;
mm.create();
cout << endl << "fire taa" << endl;
mm.taa();
cout << endl << "fire tab" << endl;
mm.tab();
cout << endl << "fire tbb" << endl;
mm.tbb();
cout << endl << "fire tba" << endl;
mm.tba();
cout << endl << "fire tdone" << endl;
mm.tdone();
}
汇编(不定义) VERBOSE_STATE_MACHINE(VERBOSE状态)。)和执行 。
pi@raspberrypi:~/sm/src $ g++ -Wall -g MM.cpp mmain.cpp
pi@raspberrypi:~/sm/src $ ./a.out
a entry
fire taa
a do
taa
fire tab
a do
a exit
tab expr
b entry
fire tbb
b do
tbb
fire tba
b do
b exit
tba expr
a entry
fire tdone
a do
a exit
tdone
pi@raspberrypi:~/sm/src $
所以 做人 在内部转换时被执行,退出状态时被错误执行,进入状态时被遗漏。
注意 状态机 生成器是 插入式 其定义是BoUML通过项目交付的一部分。sm_generator它是用C++实现的(不是用Java)。所以你可以加载项目 sm_generator在你有写入权限的情况下,保存为它,修改它,生成C++代码,编译它,并用你的新版本替换官方生成器或声明你的新版本。插入式 并将其与 状态机 的菜单中。
我修改了我的 状态机发生器,上一次是在2011年!
该 做人 不再在退出状态时执行,包括通过自我外部转换,现在是在可能的 入职. 我也是在自己内部可能的过渡行为后做的,而不是在之前做的,这样可以避免在过渡有行为的情况下,连续执行两次,中间没有任何东西。
注意已经可以通过操作来执行当前状态的可能*做行为*。doActivity 定义在与机器相关的类上。这样就可以在过渡发射之间进行。
有了之前的 状态机 稍作修改,增加一个 自身外化 :
以及 主
#include "MM.h"
#include <iostream>
using namespace std;
int main()
{
MM mm;
mm.create();
cout << endl << "fire taa" << endl;
mm.taa();
cout << endl << "fire ta_a" << endl;
mm.ta_a();
cout << endl << "fire tab" << endl;
mm.tab();
cout << endl << "fire tbb" << endl;
mm.tbb();
cout << endl << "fire tba" << endl;
mm.tba();
cout << endl << "fire tdone" << endl;
mm.tdone();
}
汇编(不定义) VERBOSE_STATE_MACHINE(VERBOSE状态)。)和执行。
pi@raspberrypi:~/sm/src $ g++ -Wall MM.cpp mmain.cpp
pi@raspberrypi:~/sm/src $ ./a.out
a entry
a do
fire taa
taa expr
a do
fire ta_a
a exit
ta_a expr
a entry
a do
fire tab
a exit
tab expr
b entry
b do
fire tbb
tbb expr
b do
fire tba
b exit
tba expr
a entry
a do
fire tdone
a exit
tdone expr
pi@raspberrypi:~/sm/src $