JS 設計模式 十三(觀察者模式)

觀察者模式

對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新。安全

觀察者要素

1.抽象主題(Subject)角色:把全部對觀察者對象的引用保存在一個集合中,每一個抽象主題角色均可以有任意數量的觀察者。抽象主題提供一個接口,能夠增長和刪除觀察者角色。通常用一個抽象類和接口來實現。ui

2.抽象觀察者(Observer)角色:爲全部具體的觀察者定義一個接口,在獲得主題的通知時更新本身。this

3.具體主題(ConcreteSubject)角色:在具體主題內部狀態改變時,給全部登記過的觀察者發出通知。具體主題角色一般用一個子類實現。code

4.具體觀察者(ConcreteObserver)角色:該角色實現抽象觀察者角色所要求的更新接口,以便使自己的狀態與主題的狀態相協調。一般用一個子類實現。若是須要,具體觀察者角色能夠保存一個指向具體主題角色的引用。server

例子

爲了生產的安全,你決定爲你的工廠安裝火警報警器,如今你須要爲這個報警器寫個控制軟件。對象

// 觀察者模式

var DP = require("./DesignPattern.js");

function Factory() {
  DP.Interface(this, ['attach', 'detach', 'nofityObserver', 'fire'])
  //添加火災報警器
  //移除火災報警器
  //通知報警器
  //發生火災
}
function FireAlarm(name) {
  var _name=name
  this.rang=function(){
    console.log(_name+':發生工廠火災了,鳴笛');
  }
}
function PorscheFactory() {
  this.__proto__ = new Factory();
  var _alarms = [];
  this.attach = function (alarm) {
    _alarms.push(alarm);
  }
  this.detach = function (alarm) {
    _alarms.splice(_alarms.indexOf(alarm),1);
  }
  this.nofityObserver = function () {
    _alarms.forEach(function(alarm){
      alarm.rang()
    })
  }
  this.fire=function(){
    console.log('工廠着火了');
    this.nofityObserver();
  }
}

var f=new PorscheFactory();
var fireAlarm1=new FireAlarm('門衛報警器');
var fireAlarm2=new FireAlarm('消防局報警器');
var fireAlarm3=new FireAlarm('門衛報警器');
f.attach(fireAlarm1);
f.attach(fireAlarm2);
f.attach(fireAlarm3);
f.fire();
console.log('--------------------------------------');
f.detach(fireAlarm3);
f.fire();

觀察者模式優勢:

1.觀察者和被觀察者是抽象耦合的。
2.創建一套觸發機制。接口

觀察者模式缺點:

1.若是一個被觀察者對象有不少的直接和間接的觀察者的話,將全部的觀察者都通知到會花費不少時間。
2.若是在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發它們之間進行循環調用,可能致使系統崩潰。
3.觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化。it

適用場景:

1.當一個抽象模型有兩個方面, 其中一個方面依賴於另外一方面。將這兩者封裝在獨立的對象中以使它們能夠各自獨立地改變和複用。
2.當對一個對象的改變須要同時改變其它對象, 而不知道具體有多少對象有待改變。
3.當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之, 你不但願這些對象是緊密耦合的。io

相關文章
相關標籤/搜索