五、 系統設計與實作
5.3 文件解析模組的實作
當解碼器將一份受保護的文件解碼後,會放置到記憶中,緊接著文件播放器 就會啟動文件解析模組,並從記憶體中讀取解碼後的資料區塊。
文件解析模組的設計方式是採用「Observer Design Pattern」,對此先做 簡單介紹,「Observer Design Pattern」的概念是:當某一個物件(object)發 生狀態上的改變時,則會通知其他具有相依性(dependency)的物件,讓這些物 件做相對應的處理與更新動作,而這些具有相依性的物件就稱作「Observer」。
[20][21]
舉例來說,當讀者在閱讀文件的過程中,對文件播放器下拉捲軸,想要觀看 其他的文件內容,則下拉時GUI 物件的狀態隨即改變,並通知文件解析模組的 Play System Observer 做相對應地處理,而 Play System Observer 就會通 知Parser Thread 到記憶體中去解析文件資料,當 Parser Thread 解析完後告 知Play System Observer,Play System Observer 隨即更新文件播放器的 內容,如圖32 所示:
圖 32、文件解析模組套用 Observer Design Pattern 的運作方式
因此,文件解析模組會一直觀察文件播放器是否有狀態上的改變,只要一有 變化,就會馬上執行相對應地處理動作。底下透過sequence diagram,再一 次詳細說明整個文件解析模組運作流程:
39
圖 33、文件解析模組之 sequence diagram
1. 當文件播放器上有事件觸發(GUI event driven),並且有狀態上的改變,
則通知文件解析模組的Play System Observer。
2. Play System Observer 設定狀態為 ready,代表準備開始處理程序,並 通知Parser Thread Observer。
3. Parser Thread Observer 接收到 Play System Observer 的通知,便開 始從記憶體中解析文件內容。
4. 當 Parser Thread Observer 解析完畢後,會將狀態設定成 done,代表 已經解析完文件內容,並告知Play System Observer。
5. Play System Observer 更新文件播放器顯示的內容(update display)。
從圖33 可以發現,文件解析模組的運作包含三種角色:GUI object、Play System Observer 與 Parser Thread Observer。GUI object 係指文件播放 器上的GUI 元件,只要有事件觸發,就會通知 Play System Observer,以下 為虛擬碼:
40 void TPlayer1::WndProc(TMessage& Message) {
接下來 Play System Observer 就會將狀態設定為 ready,並利用一個計 時器(Timer)每隔 0.1 秒檢查 Parser Thread 是否完成工作,若完成工作,則 告知Play System Observer 更新文件的顯示內容,如以下虛擬碼:
//狀態是用來監督 Parser Thread 的處理情況,共分為四種:None(在背景等候) //Ready(準備解析文件內容)、Parsing(解析中)、Done(文件內容已解析完畢) enum ParserState { None, Ready, Parsing, Done };
void PlaySystem::Processing(void) {
//Step1: 將狀態設定成 Ready
//Step2: 啟動 Timer,每 0.1 秒檢查執行緒是否將文件內容解析完畢 }
41 ParserState Timer::CheckContent(void) {
//Play System Observer 更新文件播放器顯示的內容(update display) }
}
而Parser Thread 為一個執行緒,用來解析記憶體中的文件內容,當接獲 Play System Observer 的通知(狀態設定為 ready),則開始處理工作,如以 下虛擬碼所示:
void ParserThread::Execute(void) {
透過Observer Design Pattern 的設計模式,使得文件解析模組可以更高 度模組化,且彼此之間以物件的方式作溝通,讓程式的結構性提升,降低開發的 時間成本。
42 void ProduceSceneXML(void)
{ void ProduceDocumentXML(void) { void ProduceProjectXML(void) {