再來一個已經在使用的設計模式,其實它就是 Event 的概念,但還是有點不同,
順序是這樣的,先有了 Observer 觀察者模式,用久了發現還是有些問題無法克服,
便發展出 Delegate 委派 與 Event 事件 來克服,讓人更便利的去使用。
觀察者模式的應用是什麼?
"在符合某條件的情況下,就觸發相對應的處理程序。"
例如資料進來了,就更新到UI上。或者是資料進來了,就丟給演算法去做計算。
能夠應用的情境實在是太多太多了。
Observer Pattern 觀察者模式
來看類別圖:
Subject 通知者
情境是這樣的,每次 Boss 回到辦公室的時候,都習慣會說"我回來了",佛心老闆,
而摸魚的兩位 employee 每次只要聽到 Boss 說"我回來了",就會把眼前的影片關掉。
上述的"說"就是通知者發出通知的動作,這邊命名為 Notify。
由於這個說的人可能是 Boss ,也有可能是好心的 Secretary 通風報信,
因此定義一介面 Subject 如下:
而他們除了要發出通知,也必須要知道要通知誰吧?
因此也必須透過 Attach 新增通知名單,如果不想通知他,就可以透過 Detach 刪減名單。
實作這個介面的兩個通知者類別 Boss 與 Secretary 如下:
Boss與Secretary實作內容相同,所以這邊只放Boss。
可以發現,Notify() 內會輪詢所有已被加入名單的 observer 觀察者,
一個一個呼叫他們準備相對應的 function,這邊 observer 準備的 function 為 response()。
接著來看 Observer 觀察者們應該要具備那些 function ,因此這邊定義了一個 Observer 介面。
Observer 觀察者
上面提到的"關掉"就是觀察者做出的動作,這邊命名為response。
Observer 觀察者就只要實作 response() 即可,
重點是參數必須要可以傳入 Subject 型別,這樣才知道是誰通知了 Observer。
實作這個 interface 的兩個 Observer 部分如下:
如何運作?
通知者與觀察者都完成之後,來看使用者如何操作這兩組類別。
由上而下說明,建立好場景所需的四個物件,
Boss 老闆,Secretary 秘書,兩名摸魚的 Employee 員工。
因為 Notify() 是由 Boss 與 Secretary 觸發的,因此他們必須要知道該通知誰,
以 Attach() 去加入通知名單,設定好 message 之後便呼叫 Notify() 看看。
從結果可以發現,無論是 Boss 還是 Secretary 進行呼叫 Notify() ,
兩位員工都能夠收到通知並做出回應,幾乎是達成了我們常用的 Event 功能。
但你是否有發現哪邊是否可以改善?
Observer 觀察者模式應改善的地方?
第一點,拉回去看看 Subject 介面所定義的,
它只限定有實作 Observer 介面的物件能夠加入清單,
如果你想要被通知的類別並沒辦法讓你實作 Observer 介面該怎辦?
如果我想要被 Subject 介面 呼叫的 Observer 介面方法不想稱作 response() 怎辦?
第二點,拉回去看看 Observer 介面所定義的,
它的 response() 也限定必須是實作 Subject 介面的類別才能傳入,
如果我想同時讓不同類別的物件都觸發同一個 response() 該怎辦?
難道要一個類別就宣告一個 response() 去對應嗎?
結論就是,
"Observer 觀察者模式耦合了 Subject 介面 與 Observer 介面。"
改善方式?
那如何改善呢?
如果我想要 Subject 通知者 不需要知道是誰需要通知,
條件一但成立就發出訊息通知 Observer 觀察者。
如果我想要 Observer 觀察者都是不同類型,也不需要實作相同的 Observer 介面,
卻都能夠被 Subject 通知者 呼叫呢?
這時候我們就能透過 Delegate 委派 與 Event 事件 來克服這些問題,
下一篇將會介紹透過 Delegate 委派 與 Event 事件 來實作的觀察者模式。
沒有留言:
張貼留言