iT邦幫忙

2022 iThome 鐵人賽

DAY 24
0

行為型模式:觀察者模式 Observer Design Pattern

如果你用過Vue的Watcher,那你就大概了解了觀察者模式啦。
觀察者模式指的是可以[訂閱]一個對象,
而對象有更新的話就會發通知給你。
(也有人說是訂閱發布模式publish-subscribe pattern)

這些都是觀察者模式喔

  1. MVC Model
  2. JS的event listener
  3. 訂閱網站消息

或想像一下,你很想買新的iPhone,但你每次跑去商店確認都還沒進貨。
這樣不是一進貨,商店就通知你來的更有效率嗎?

** 使用情境 **

  1. 當一個目標變動時,另外一個東西也要變動 (iPhone一進貨-->你就要花錢買啦)
  2. 但目標變動的時間無法掌握,必須一直觀察

觀察者模式應用在"物件彼此溝通"的過程,
因此被歸類在"行為型模式"(還記得我們的三大分類嗎?)

TS 案例

那我們就來用iPhone例子寫寫觀察者模式吧!

Rachel我是一家商店,而Gary和Cindy都想要知道最新iPhone進貨的消息。

這邊我用倒敘法寫,所以跑到TS會報錯喔。
把順序搞對,可以來TS Playground試試看

//我們一樣倒過來看

//1.來訂閱最新商店進貨消息吧
//我是一家商店,創建一個商店通知系統實體
const rachelStoreNotifySystem = new storeNotifySystem();
//我的顧客Gary & Cindy都想要iPhone進貨的消息,
//幫他們訂閱系統
const garyWantsaNewIphone = new Observer("gary");
const cindyWantsaNewIphone = new Observer("cindy");


//猜猜會印出啥
//我來把Gary和Cindy加入我的通知清單
rachelStoreNotifySystem.subscribe(garyWantsaNewIphone);
rachelStoreNotifySystem.subscribe(cindyWantsaNewIphone);
//通知他們進貨囉!
rachelStoreNotifySystem.notify("We have stocks for new iPhones!");
//來看看gary和cindy收到什麼消息
garyWantsaNewIphone.showFeed();
cindyWantsaNewIphone.showFeed()

//[LOG]: "gary 收到通知囉!" 
//[LOG]: "cindy 收到通知囉!" 
//[LOG]: "gary:We have stocks for new iPhones!" 
//[LOG]: "cindy:We have stocks for new iPhones!" 

//2.來看看這些系統裡有啥
//我們的訂閱系統
class storeNotifySystem implements Target {
    private observers:Observer[] = [];
    subscribe(observer:Observer) {
        this.observers.push(observer)
    }
    notify(news:string) {
        this.observers.forEach(observer => {
        //注意這邊是呼叫傳入觀察者的更新函式:依賴倒置原則
            observer.update(news);
        })
    }
}

class Observer implements ObserverTemplate {
    constructor(public readonly name:string) {}
    private feed:string[] = []; 
    update(news:string) {
       this.feed.push(news)
       console.log(`${this.name} 收到通知囉!`)
    }
    showFeed() {
        console.log(this.name + ":" + this.feed)
    }
}

//3.來看看模型
interface Target {
    subscribe(observer: Observer):void
    notify(news:String):void
}

interface ObserverTemplate {
    update(news:string):void
}

改寫引用自:Observer Design Pattern Implementation in Typescript

應用到的原則

  1. 開關原則 Open-Close principle (OCP)
    1. 添加新的訂閱者,而不用修改發布者(Publisher/我們的Target class)的code
  2. 依賴反轉原則 Dependency inversion principle (DIP)
    1. 發布者要發布消息時,是呼叫觀察者的update,如果觀察者選擇修改update,也跟發布者無關,降低兩者耦合度


環遊非洲第24天-動物大遷徙

以為所有的非洲國家都可以看動物大遷徙?Nonono,很多非洲國家
的確有國家公園可以看Big 5 (大象、獅子、水牛、犀牛、獵豹)
但是大匹動物們逐水草的景象,只有在肯亞和倘桑尼亞看得到喔!

動物大遷徙發生在一年四季,發生在倘桑尼亞的賽倫蓋提(Serengeti)
至肯亞馬賽馬拉(masai mara)國家公園。(嚴格來說馬賽馬拉也屬於賽倫蓋提的一部分)
只要當地的乾季來臨,百萬隻動物們開始移動,
跟著雨季追尋新鮮的草原。

最著名的渡河場景,發生在7-9月肯亞的馬賽馬拉。
也是為什麼肯亞的觀光名氣很大囉!

要開放國界囉!想去非洲看大遷徙但還是抽不出時間&金錢的,
也可以看看旅行社的介紹照片很美,介紹很精采,過過癮。
(絕對沒有葉配哈哈。)
動物大遷徙 | 肯亞+坦尚尼亞11日

https://ithelp.ithome.com.tw/upload/images/20221009/20140247BILwqURwac.jpg
圖片來源



參考

Observer Design Pattern Implementation in Typescript
What SOLID principles does the observer pattern follow/violate?
10. 從被動變主動—依賴反轉
Design Patterns- Observer


上一篇
抽象工廠模式-用TS挑戰設計模式-D23
下一篇
組合模式-用TS挑戰設計模式-D25
系列文
分手前端菜雞之旅@非洲30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言