進擊的觀察者模式

2021-09-11 14:56:44 字數 4092 閱讀 4696

talk is cheap. show me the code. (譯: 屁話少說, 放碼過來)

以下所有**參見design pattern transformation.

// 商品的資訊: ** & 折扣

const data =

// 顧客資訊: 是否為會員 & 購買數量 & 總消費 & 購買時間戳

const customer =

// 總消費計算方式

total = (info) => else

}total(customer);

console.log('customer', customer);

// customer

複製**

從**中很容易看得出來, 我們就是想實現乙個簡單的計費功能. 可現實中, 商品的**可能並不是一成不變的.

data.price = 200

**變動後, 我們需要及時地獲取總消費, 那麼就必須重新呼叫下total計費.

total(customer);

console.log('customer', customer);

// customer

複製**

這是乙個大資料時代, 任何資料都有價值. 現在, 我們還想要每次購買時的時間點.

const customer = 

// 獲取購買時間

purchasetime = (info) =>

複製**

於是, 我們需要執行的函式就多了乙個.

total(customer)

purchasetime(customer)

console.log('customer', customer)

// 複製**

如果我們的需求還有很多, 而且不知乙個customer呢. 那麼, 每次**變化我們需要執行很多步驟, 每次啊, 麻煩得很.

+    const customer1 = 

total(customer)

purchasetime(customer)

func(customer)

...funcn(customer1)

total(customer1)

purchasetime(customer1)

func(customer1)

...funcn(customer)

...funcn(customern)

複製**

現在我們就對上面的**進行觀察者模式改造.

從上面的例子中??️不難看出, 每次**變化時, 我們都需要重複呼叫滿足需求的方法. 不妨想想, 如果我們把這些方法儲存起來, 等到**變化時再去統一呼叫, 豈不是很方便. 那麼問題來了, 這和之前所說的觀察者模式(從觀察者模式說起)有什麼區別呢? 在此, 我們試著用觀察者模式改造下. 首先觀察者模式都是乙個套路. 先乙個類維護乙個列表, 對列表有增刪和通知更新功能. 另乙個類則是提供了更新介面.

// 觀察目標類

class

subject

addobserver(observer)

notify(params) )

}}// 觀察者類

class

observer

}複製**

接著, 把我們想要呼叫的方法包裝一下, 儲存起來.

// 將要重複使用的包裝一下

observer1 = new observer(total)

observer2 = new observer(purchasetime)

// 存起來

let subject = new subject()

subject.addobserver(observer1)

subject.addobserver(observer2)

複製**

每次**改變時, 只需要通知一下即可.

// 調整商品**

data.price = 100

subject.notify(customer)

subject.notify(customer1)

複製**

改造結束. 初看起來, 可能變得繁瑣了. 但是, 遇到複雜的情況, 這不失是乙個好辦法. 接下來, 我們看看結合objec.defineproperty會有什麼驚喜.

支付寶的花唄都可以自己還錢了?, 我們為什麼還要別人管著?. 大家都知道經過objec.defineproperty處理的物件, 在設定和獲取物件屬性的時候, 會自動觸發響應setget方法. 利用這一點, 我們就可以做到生活自理了. 熟悉的配方, 熟悉的味道. 熟悉的套路我們不妨再走一遍.

// 觀察目標類

class

dependency

addobserver(observer)

notify(params) )

}}// 觀察類

class

watcher

}複製**

我們此行的目的, 是要在data.pricedata.discount改變時, 程式能夠自動觸發, 得到我們想要的結果. 換句話說, 通知更新的時機是在設定data.pricedata.discount的時候.

object.keys(data).foreach(key => ,

get()

})})複製**

物件的每個屬性都給了乙個依賴例項, 管理自己的依賴. 考慮到customer有很多個, 需要通知到位. 另外, 新增依賴和管理依賴, 前者是因, 後者是果. 在管理之前我們需要想好怎麼新增依賴. 回頭看一看.

// 總消費計算方式

total = (info) => else

}// 獲取購買時間

purchasetime = (info) =>

複製**

我們發現,total函式依賴於data.pricedata.discount的. 如果我們在獲取屬性時去新增依賴倒是乙個好時機.

class dependency 

+ dependency.targey = null;

class watcher

+ getter()

}object.keys(data).foreach(key => ,

get()

return value}})

})複製**

然而purchasetime方法裡並沒有data.pricedata.discount可以設定. 所以這個方法行不通. 那麼, 乾脆緊接著依賴例項去新增依賴吧. 同時考慮到多個customer, 我們封裝下.

// 與defineproperty結合

function

definereactive(data, watcherlist, funclist) )

object.defineproperty(data, key, )

},get()

})})

}definereactive(data, [customer, customer1], [total, purchasetime])

複製**

大功告成, **變動時, 我們就會自動獲取到想要的結果了. 我都能自理了, 你花唄為嘛還不能自己還錢呢?

觀察者模式系列:

python觀察者模式 python 觀察者模式

python 觀察者模式 前言e 寫的倉促就不截uml類圖了,書本chapter10,p313能看到圖 一旦觀察的主題有更新,就會通知到觀察者們,下面的例子是最簡單的乙個觀察者範例,假設這是一群投機分子密切關注 軍 火 倉庫的產品與數量變動 class inventory def init self...

觀察者模式

觀察者模式 observer 完美的將觀察者和被觀察的物件分離開。舉個例子,使用者介面可以作為乙個觀察者,業務資料是被觀察者,使用者介面觀察業務資料的變化,發現資料變化後,就顯示在介面上。物件導向設計的乙個原則是 系統中的每個類將重點放在某乙個功能上,而不是其他方面。乙個物件只做一件事情,並且將他做...

觀察者模式

觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某乙個主題物件。這個主題物件在狀態上發生變化時,會通知所有觀察者物件,讓他們能夠自動更新自己 任何乙個模式都是離不開角色的,這裡也會有幾種角色 抽象主題角色 把所有對觀察者物件的引用儲存在乙個集合中,每個抽象主題角色都可以有任意數量的觀察...