當前位置:
首頁 > 知識 > javaScript 設計模式系列之一:觀察者模式

javaScript 設計模式系列之一:觀察者模式

介紹

觀察者模式又叫發布訂閱模式(Publish/Subscribe),一個目標對象管理所有相依於它的觀察者對象。該模式中存在兩個角色:觀察者和被觀察者。目標對象與觀察者之間的抽象耦合關係能夠單獨擴展以及重用。

該模式通常有兩種實現策略:"推"(push) 和 "拉"(pull)


例:對於報社可能僱傭投送人員四處送報給訂閱者,這就是主動推送。而對於規模小的報社沒有足夠的資源去僱傭投送員,這時候可以採取 "拉" 的方式。就是在訂閱者附近提供自己的數據,供訂閱者 "拉" 自己所需的數據。

實現push

var Observable = {
observers:
, lastId: -1
, addObserver: function(observer) {
this.observers.push({
callback: observer
, id: ++this.lastId
})

return this.lastId
}
, removeObserver: function(id) {
for (var i = this.observers.length - 1; i >= 0; i--) {
this.observers[i]
if (this.observers[i].id == id) {
this.observers.splice(i, 1)
return true
}
}

return false
}
, notifyObservers: function(message) {
for (var i = this.observers.length - 1; i >= 0; i--) {
this.observers[i].callback(message)
};
}
}

var id_1 = Observable.addObserver(function(message){
console.log("First observer message:" + message)
})

var observer = function(message){
console.log("Second observer message:" + message)
}

var id_2 = Observable.addObserver(observer)

Observable.notifyObservers("test 1")
Observable.removeObserver(id_2)
Observable.notifyObservers("test 2")

pull

var Observable = {}

;(function(O){
var observers =
, privateVar

O.addObserver = function(observer) {
observers.push(observer)
}

O.removeObserver = function(observer) {
var index = observers.indexOf(observer)

if (~index) {
observers.splice(index, 1)
}
}

O.notifyObservers = function {
for (var i = observers.length - 1; i >= 0; i--) {
observers[i].update
};
}

O.updatePrivate = function(newValue) {
privateVar = newValue
this.notifyObservers
}

O.getPrivate = function {
return privateVar
}
}(Observable))

Observable.addObserver({
update: function{
this.process
}
, process: function{
var value = Observable.getPrivate
console.log("Private value is: " + value)
}
})

Observable.updatePrivate("test 1")
// Private value is: test 1

Observable.updatePrivate("test 2")
// Private value is: test 2

被觀察對象將通知所有的觀察者,並且每個觀察者將從被觀察對象中提取所需的信息。

讓多個對象都具有觀察者發布訂閱的功能

var observer = {
addSubscriber:function (callback) {
this.subscribers[this.subscribers.length] = callback;
},
removeSubscriber:function (callback) {
for (var i = 0; i < this.subscribers.length; i++) { if (this.subscribers[i] === callback) { delete(this.subscribers[i]); } } }, publish:function (what) { for (var i = 0; i < this.subscribers.length; i++) { if (typeof this.subscribers[i] === "function") { this.subscribers[i](what); } } }, make:function (o) { // turns an object into a publisher for (var i in this) { o[i] = this[i]; o.subscribers = ; } } }; var blogger = { writeBlogPost:function { var content = "Today is " + new Date; this.publish(content); } }; var la_times = { newIssue:function { var paper = "Martians have landed on Earth!"; this.publish(paper); } }; observer.make(blogger); observer.make(la_times); var jack = { read:function (what) { console.log("I just read that " + what) } }; var jill = { gossip:function (what) { console.log("You didn"t hear it from me, but " + what) } }; blogger.addSubscriber(jack.read); blogger.addSubscriber(jill.gossip); blogger.writeBlogPost; blogger.removeSubscriber(jill.gossip); blogger.writeBlogPost; la_times.addSubscriber(jill.gossip); la_times.newIssue;

避免創建多個被觀察者對象,可以增加 "命名空間"

var Observable = {
observers:
, addObserver: function(topic, observer) {
this.observers[topic] || (this.observers[topic] = [])

this.observers[topic].push(observer)
}
, removeObserver: function(topic, observer) {
if (!this.observers[topic])
return;

var index = this.observers[topic].indexOf(observer)

if (~index) {
this.observers[topic].splice(index, 1)
}
}
, notifyObservers: function(topic, message) {
if (!this.observers[topic])
return;

for (var i = this.observers[topic].length - 1; i >= 0; i--) {
this.observers[topic][i](message)
};
}
}

Observable.addObserver("cart", function(message){
console.log("First observer message:" + message)
})

Observable.addObserver("notificatons", function(message){
console.log("Second observer message:" + message)
})

Observable.notifyObservers("cart", "test 1")
// First observer message:test 1

Observable.notifyObservers("notificatons", "test 2")
// Second observer message:test 2

相關閱讀

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 科技優家 的精彩文章:

Swift 中 String 取下標及性能問題
.Net Core中使用ref和Span提高程序性能
每天一道Java題「4」
MySQL 的性能(上篇)——SQL 執行時間分析
linux c++爬蟲(一)

TAG:科技優家 |

您可能感興趣

「設計模式專題」Singleton
static 單例模式autoptr與單例模式const 用法小結mutable修飾符
web api之selfhost模式
刨銑acessemarketing商業模式
Ghost Recon Wildlands更新將使用Permadeath 模式
iOS 12 beta 5 開發者測試版暗示「iPhone X Plus」將有 iPad 的橫屏模式
Google Assistant登陸iPad平板:支持多任務模式
《Avengers: Infinity War》將與《Fortnite》推出聯乘模式
微軟Outlook.com beta上線暗黑模式
Flutter 的編譯模式
谷歌AR Sticker改為Playground,作為Pixel相機新模式
Chrome OS多屏模式下更像Windows
Android P Beta 3「暗黑模式」改進
任天堂Switch豎向掌機模式配件上架kickstarter眾籌平台
Zynga的《CSR Racing 2》AR模式進入Android設備
雙HomePod立體聲模式叫做FullRoom
像Mac一樣裝Win 10!Pixelbook驚現雙系統模式
新技能Get!Bosesoundlinkrevolve+的派對模式怎麼玩才過癮?
哄搶模式開啟!Virgil Abloh x Air Jordan 1發售信息官方確認!
網路專家解讀YouTube,Twitter或Reddit的盈利模式