注意:
例如:
class MyClass { public: void open(); void connect(); void read(); void write(); void disconnect(); void close(); private: ... }; 使用規則:物件必須在沒有開啟的狀況下呼叫 open() 才有作用, 必須要已經 open() 過後才能夠呼叫 connect(),必須 要是 connected 的狀況下才能做 read/write/disconnect, 必須要是 disconnected 且有 open 過才能呼叫 close()
正確用法: | 錯誤用法: | |
MyClass obj; obj.open(); obj.connect(); obj.read(); obj.disconnect(); obj.close(); |
MyClass obj; obj.open(); obj.read(); |
void open() { if (!m_fOpen) { m_fOpen = true; do_open(); } } |
void close() { if ((m_fOpen)&&(!m_fConnected)) { m_fOpen = false; do_close(); } } |
|
void connect() { if ((m_fOpen)&&(!m_fConnected)) { m_fConnected = true; do_connect(); } } |
void disconnect() { if (m_fConnected) { m_fConnected = false; do_disconnect(); } } |
|
void read() { if (m_fConnected) do_read(); } |
void write() { if (m_fConnected) do_write(); } |
上面程式的考慮周全了嗎? 兩個 flag 共有 4 種狀況, 可是每一個訊息處理函式中似乎都只考慮到部份的狀況, 其它的狀況呢?
首先 m_fOpen 及 m_fConnected 兩個 flag 可以定義出 4 種狀況, 其中有意義的有三種如下表, 表中並指定每一種狀況一個狀態的名稱:
m_fOpen | m_fConnected | 對應狀態 | |
false | false | Closed | |
true | false | Opened | |
true | true | Connected |
在下面的狀態圖中我們考慮三種狀態以及六種輸入訊息 (事件), 這三種狀態是 Closed, Opened, 及 Connected, 六種訊息是 open, connect, read, write, disconnect, close
製作訊息 open 處理函式 open() 的方法如下:
void open() { if (m_state == Closed) { do_open(); m_state = Opened; } } |
void close() { if (m_state == Opened) { do_close(); m_state = Closed; } } |
|
void connect() { if (m_state == Opened) { do_connect(); m_state = Connected; } } |
void disconnect() { if (m_state == Connected) { do_disconnect(); m_state = Opened; } } |
|
void read() { if (m_state == Connected) do_read(); } |
void write() { if (m_state == Connected) do_write(); } |
注意:
void close() { if (m_state == Opened) { do_close(); m_state = Closed; } else if (m_state == Connected) { do_disconnect(); do_close(); m_state = Closed; } } |
在任何一種狀態下應該要考慮所有可能收到的訊息, 才不會在某些沒有考慮到的操作狀況下產生不合適的反應。
類別關係圖及物件關係圖是設計程式者與使用此應用程式的人心中共同的靜態應用模型 (conceptual model), 必需反映實際世界中真實的系統運作模型, 每一個不同的物件的狀態圖則是該物件的完整動態模型, 這兩種圖可以說完整地刻劃了整個物件系統, 一般同一個程式計劃中不同的設計人員在討論時並不直接交換程式碼, 而是共同討論這些圖片, 這些圖片也可以和提出系統需求的使用者來溝通, 同時也是系統標準文件中最重要的一部份。
基本上每一個類別是一個模組, 和外界其它的物件之間只透過定義好的界面來溝通, 在製作這個類別中的事件處理函式時不應該假設其它物件會以某種特定的方法來使用此物件, 這也就是為什麼在每一個狀態下我們都需要考慮所有可能發生的訊息的原因, 在很多情況下, 物件不會去處理一些不該出現的訊息, 也就是狀態圖中標示 NOP 的意義, 但是這些不該出現的訊息, 常常也設計成導致一些警告的訊息來提醒其他的物件他們的使用方式有誤, 例如上例中:
回
C++ 程式設計課程
首頁
製作日期: 5/11/2000
by 丁培毅 (Pei-yih Ting)
E-mail: pyting@cs.ntou.edu.tw