設計相關6--觀察者模式

定義

觀察者模式也叫訂閱發佈者模式。訂閱者們訂閱某主題,當主題數據或者狀態發生變化時,通知訂閱了本主題的訂閱者們進行更新。

組成及類圖

  • 抽象主題Subject
    (1) 抽象主題可以是一個抽象類或者一個接口。
    (2)擁有一個新數對象或者一個狀態屬性。
    (3)擁有一個觀察者集合,存放訂閱了本主題的觀察者們。可在實例化主題時,實例化這個集合屬性。
    (4)支持通知觀察者們。當數據更新或者狀態發生變化時,推送新數據給訂閱了本主題的觀察者們,通知他們進行自動更新。
    (5)支持添加某個觀察者。
    (6)支持移除某個觀察者。
  • 具體主題
    (1)實現抽象主題的各個抽象方法。
    (2)主題不用關心數據是何時變化的,如何變化的。當數據變化時,通過set方法將新數據傳給主題,在set方法裏通知觀察者們。
  • 抽象觀察者Observer
    (1)抽象觀察者可以是一個接口或者一個抽象類。
    (2)擁有一個訂閱的主題。
    (3)支持訂閱主題成爲觀察者。
    (4)支持取消訂閱,數據更新時不要再通知我了,i dont care!!
    (5)支持更新數據,然後乾點啥。
  • 具體觀察者
    (1)擁有一個抽象主題的引用。提供set方法支持主題的更改,並在set方法裏進行訂閱註冊。
    (2)實現觀察者抽象方法。

  • 類圖
    稍後上傳。。。

場景舉例

某化妝品品牌的VIP會員註冊功能。只有註冊爲VIP會員,纔會收到本店的打折消息和優惠。當然,你是土豪的話,也可以隨時退訂。

模式總結

(1)觀察者模式很好的降低了主題和觀察者之間的耦合度。主題不用關心自己具體有哪些訂閱者,訂閱者可以隨時訂閱或者取消訂閱主題,而不用更改主題代碼。
(2)數據同步有兩種方式,一種是觀察者訂閱主題,通過主題的get方法,從主題那裏拿;另一種是觀察者訂閱主題,在主題通知觀察者更新時,推送數據給觀察者們。個人比較支持第二種,覺得主題不應該提供數據的get方法。因爲提供get方法的話,觀察者只要擁有主題的引用,不用訂閱,不就可以拿到新數據了嗎!?要知道,主題纔是數據的擁有者,數據的分配權歸主題所有,不是誰想拿就能拿的。
(3)主題擁有數據,主題怎麼獲得外界的新數據呢,大多數人肯定想通過set方法唄,可是這樣的話,訂閱者可能會通過主題引用更改數據。要注意set方法的訪問權限。
(4)留下幾個疑問:

爲啥把主題抽象成接口或抽象類?
提高一個模塊(接口、抽象類)的複用潛力,使我們設計的目標!

觀察者模式就是一對多的依賴,不能是多對多的依賴嗎?比如一個觀察者訂閱多個主題?

如果主體的數據來自外界其他模塊,它就不得不通過set方法獲得新數據,此時觀察者們很可能通過這個set方法更改數據的!咋整呢??

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章