一個對象(subject)維持一系列依賴於它(觀察者)的對象,將有關狀態的任何變動自動通知給它們。this
當一個目標須要告訴觀察者發生了什麼有趣的事情,它會向觀察者廣播一個通知prototype
當咱們再也不但願某個特定的觀察者獲取其註冊目標發出的改變通知時,該目標能夠將它從觀察者列表中刪除。code
Observer(觀察者)模式列表組件server
Subject(目標): 維護一系列觀察者,方便添加或刪除觀察者對象
Observer(觀察者): 爲那些在目標狀態發生改變時需得到通知的對象提供一個更新接口接口
ConcreteSubject(具體目標):狀態發生改變時,向Observer發出通知,存儲ConcreteObserver的狀態io
ConcreteObserver(具體觀察者):存儲一個指向ConcreteSubject的更新接口,實現Observer的更新接口,以使自身狀態與目標的狀態保持一致。console
1.1 模擬擁有的一系列依賴Observerfunction
function ObserverList(){ this.observerList = []; } ObserverList.prototype.Add = function(obj){ return this.observerList.push(obj); }; ObserverList.prototype.Remove = function(obj){ return this.observerList.pop(obj); }; ObserverList.prototype.Empty = function(){ this.observerList = []; }; ObserverList.prototype.Count = function(){ return this.observerList.length; }; ObserverList.prototype.Get = function(index){ if(index > -1 && index < this.observerList.length){ return this.observerList[index]; } }; ObserverList.prototype.Insert = function(obj,index){ var pointer = -1; if(index === 0){ this.observerList.unshift(obj); pointer = index; }else if(index === this.observerList.length){ this.observerList.push(obj); pointer = index; } return pointer; }; ObserverList.prototype.IndexOf = function(obj,startIndex){ var i = startIndex, pointer = -1; while(i < this.observerList.length){ if(this.observerList[i] === obj){ pointer = i; } i++; } return pointer; }; ObserverList.prototype.RemoveIndexAt = function(index){ if(index === 0){ this.observerList.shift(); }else if(index === this.observerList.length - 1){ this.observerList.pop(); } }; //使用extension擴展對象 function extend(obj,extension){ for(var key in obj){ extension[key] = obj[key]; } }; var liuyidi = {}; var observer = new ObserverList(); extend(observer,liuyidi); console.log(liuyidi);
1.2 模擬目標(Subject)和在觀察者列表上添加、刪除或通知觀察者擴展
function Subject(){ this.observers = new ObserverList(); } Subject.prototype.AddObserver = function(observer){ this.observers.Add(observer); }; Subject.prototype.RemoveObserver = function(observer){ this.observers.RemoveIndexAt(this.observers.IndexOf(observer,0)); }; Subject.prototype.Notify = function(context){ var observerCount = this.observers.Count(); for(var i = 0; i < observerCount; i++){ this.observers.Get(i).Update(context); } };