例子不是影響他人的主要素材,是唯一素材。 ————原書引用。
這一篇主要以官方提供的哲學(xué)家就餐的例子,來引出順序圖、活動對象、到整體的設(shè)計與應(yīng)用,一切從需求開始,一張圓形的桌子上圍坐了五個哲學(xué)家,圓桌上有一盆意大利面,在哲學(xué)家的兩側(cè)都有餐叉,哲學(xué)家的日常由思考和吃面組成,思考一段時間,餓了,然后吃面一段時間,然后再思考,但是有個問題,就是面條太滑,如果想要吃面就得用兩把叉子,這個時候出現(xiàn)了一個問題,當(dāng)一個吃面的時候,身邊的另外兩個人就不能同時吃面了,因為餐叉有限,有人獲得了,身邊的人就只能等待,如圖:
在這個例子中,我們很明顯能夠確認(rèn)的是,餐叉相當(dāng)于是一種資源相對于哲學(xué)家,基于上一篇,我們規(guī)則里面,一般情況下將這種共享的資源封裝在一個活動對象內(nèi),統(tǒng)一管理,這里就有了第一個名為table的活動對象,負(fù)責(zé)管理餐叉,因為餐叉都是放在桌子上的,所以其名為table。除了這個共享的資源以外,看一看誰來申請餐叉,哲學(xué)家,同時,他還有不同的狀態(tài),思考,饑餓,用餐等等。所以很符合狀態(tài)機的模式,于是將哲學(xué)家也封裝成活動對象,整個應(yīng)用便是通過活動對象之間的交互完成的。
接下來需要分離出整個應(yīng)用當(dāng)中需要的事件信號,這時候需要繪制順序圖,順序圖如下:
這個圖很有意思,最左上是QF提供基礎(chǔ)的服務(wù)項,往右都是我們定義的活動對象,
從每個活動對象垂直看下去,就是活動對象在交互過程中的狀態(tài)轉(zhuǎn)換歷史,而帶箭頭的部分就是我們最需要的事件,從圖中可以看到箭頭上的說明是事件的信號,箭頭的方向是指示了事件的發(fā)送者到接收者。
一般事件信號的定義和事件類型的定義都會放在一個公共的頭文件中,因為事件是用來交互的,他會涉及很多的活動對象,所以共享是這些是必要的,例如我們的應(yīng)用中,事件信號的枚舉,事件結(jié)構(gòu)體的定義。這里都放在了dpp.h中:
除了這些內(nèi)容以外,共享的宏,以及構(gòu)造函數(shù)的聲明也要放到這個文件中,因為main.c中要顯式的調(diào)用這些構(gòu)造函數(shù)。
在main函數(shù)中,你需要給每個活動對象創(chuàng)建一個事件隊列,給動態(tài)申請的事件創(chuàng)建內(nèi)存池,給發(fā)行訂閱機制初始化隊列,如下:
定義好了事件池以后,就要構(gòu)造活動對象、初始化系統(tǒng)框架、初始化發(fā)行訂閱機制、初始化事件池、初始化板級資源,如下:
接下來,啟動活動對象,并把系統(tǒng)控制權(quán)交回給QF,如下:
到這里我們的應(yīng)用也就真正的運行起來了。