[答疑]解析美女出的一道狀態機題(x、y和z值)
- 2019 年 10 月 6 日
- 筆記
狀態機如下圖所示。如果對象創建之後,事件e2、e1、e3、e4、e1和e5按給定順序發生,請問,事件發生結束後,變數x、y和z值分別是_______________________。

【答案】
x=-1,y=1,z=0。
【解析】
競賽題的絕大多數題目是我自己出的,但本題來自Martina Seidl等所著的「UML @ Classroom」。
這道題目覆蓋了狀態機圖的各個知識要點。
先補充解釋可能比較陌生的概念:
(1)歷史狀態。
歷史狀態(帶圓圈H)記錄最近一次離開一個組合狀態之前所處的子狀態。淺歷史狀態(不帶*號)只記住同一層的子狀態,深歷史狀態(帶*號)可以記住更深的子狀態。
歷史狀態有向外的遷移,表示如果歷史狀態空白,那麼預設遷移到該遷移的目標狀態。這個地方經常有人誤解,以為遷移到歷史狀態就等於遷移到歷史狀態向外遷移所指向的目標狀態。想想就知道是錯的,如果是這樣,中間插入一個歷史狀態不是多此一舉嗎?
(2)完成遷移。
不帶觸發事件的遷移,在到達狀態的終態時隱式觸發。
再說一下執行順序。無警戒條件或警戒條件為真,按以下順序執行:
(1)源狀態的出口活動,先子後父;
(2)遷移上的動作和消息;
(3)改變狀態;
(4)目標狀態的入口活動,先父後子。
一開始,狀態機預設進入A。在進入A之前,執行遷移上的動作x=2。進入A時,執行A的入口活動z=0。
e2發生,狀態機離開A遷移到C。離開A時,執行A的出口活動z++,z的值變為1。然後,執行遷移上的動作z=z*2,z的值變為2。進入組合狀態C時,執行C的入口活動z++;y=2。z的值變為3,y的值變為2。C的預設子狀態是C1,狀態機進入C1,執行C1的入口活動z=z*2,z的值變為6。
e1發生,狀態機保持在C1,執行動作x=4,x的值變為4。
e3發生,先檢查遷移的警戒[z==6]。因為z當前值為6,警戒[z==6]為真。狀態機離開C1,執行C1的出口活動z=3,z的值變為3。進入C2時,執行C2的入口活動y=0,y的值變為0。
e4發生,狀態機離開C2,執行C2的出口活動x=-1,x的值變為-1。然後,狀態機離開C,執行C的出口活動y=1,y的值變為1。淺歷史狀態記住離開時所處的同一層的子狀態C2。然後狀態機進入E,執行E的入口活動y++,y的值變為2。
e1發生,狀態機返回歷史狀態,即C2。先父後子執行入口活動。先執行C的入口活動z++;y=2。z的值變為4,y的值變為2。然後執行C2的入口活動y=0,y的值變為0。
e5發生,狀態機離開C2,執行C2的出口活動x=-1,x的值變為-1。狀態機遷移到C的終止狀態,觸發了完成遷移。圖上有完成遷移由C指向A。離開C時,執行C的出口活動y=1,y的值變為1。狀態機進入A時,執行A的入口活動z=0。因此,最終x=-1,y=1,z=0。
用表格表示如下:
事件 | 狀態 | 歷史 | x | y | z |
|---|---|---|---|---|---|
開始 | A | 2 | 0 | ||
e2 | C1 | 2 | 6 | ||
e1 | C1 | 4 | |||
e3 | C2 | 0 | 3 | ||
e4 | E | C2 | -1 | 2 | |
e1 | C2 | 0 | 4 | ||
e5 | A | -1 | 1 | 0 |