觀察者模式:定議java
定義對象間的一種一對多的關係,當一個對象狀態改變時 (通常稱爲被觀察者),依賴於該對象的對象被通知,並更新;編程
觀察者模式:說明數組
1. 觀察者模式是行爲模式,也被稱爲:發佈-訂閱模式、模型-視圖模式、源-監聽器模式、從屬者模;this
2. 面對象過程當中觀察者模式的組成:編碼
1>. 抽象主題角色:這個角色裏,定義維護了一份對觀察者列表的管理集,一組用數組來存放,並定義了對一些基礎的接口,比例用來添加跟刪除觀察者的方法;spa
2>. 具體主題角色:這個角色,對於與客戶,具體業務狀態數據交互,並作必定的處理,而後再通知各個觀察者 更新本身;prototype
抽象跟具體主題裏的 一些經常使用的方法接口,若是 add|delete 或 notified方法,在哪一個方法不是固定的; add跟delete也能夠出如今 具體的主題角色裏;code
3>. 抽象觀察者角色:爲全部觀察者定義一個統一的接口,這個接口叫更新接口;server
4>. 具體觀察者角色:實現抽象觀察者角色的各自的更新方法;對象
3. 執行過程:
4. 觀察者模式-結構圖:
5. 場景實例描述:
1>. 好比說母親通知孩子吃飯的例子,一個家裏有一兩個孩子,這兩個小孩子有點調皮,喜歡亂跑,媽媽把飯煮好了,可是看不到小孩的身影,叫也沒見小孩迴應回來的,因此媽媽就在小孩身上裝了個 通知設備,一到把飯煮好,媽媽就在一個通知設備上按個按鈕,就能夠小孩身上的設備上發出聲音:‘飯煮好了,快點回來吃飯’,而後小孩就能夠立刻回來吃剛上桌溫熱的飯菜了;
2>. java的事件監聽機制包括:事件源,事件監聽器,事件對象;
事件監聽器至關於觀察者,觀察者用於提供統一的更新方法;
事件源與事件對象至關於被觀察者 (具體主題對象)
6. 觀察者模式所應用到的原則: 對象的單一性質原則,開閉原則等;開閉原則所體現到的就是面對對象編碼所提到要以接口來編程的原則,這樣程序對象間就能夠更好的複用及解耦;
7. 觀察者模式主要組成: 被觀察對象(目標對象, 具體對象, 主題), 觀察者 (訂閱者, 監聽者), 事件(更新方法);
8. 當具體觀察者對象的更新方法接收爲普通類型數據,好比 string 時, 通常稱爲「推」模式;
當 更新方法傳遞的是,被觀察者(具體主題對象)時,通常被稱爲「拉」模式;
源碼實例
1. 主題對象:
function Subject() { this.Observers = []; } Subject.prototype.add = function(observer) { this.Observers.push(observer); } Subject.prototype.remove = function(observer) { var me = this; for (idx in me.Observers) { if (me.Observers[idx] == observer) { me.Observers[idx].splice(idx, 1); break; } } } //推模式 Subject.prototype.notifyState = function(info) { var me = this; for (idx in me.Observers) { me.Observers[idx].update(info) } } //接模式 Subject.prototype.notifyObservers = function(subject) { var me = this; for (idx in me.Observers) { me.Observers[idx].updateSubject(subject) } }
2. 具體主體對象
function ConcreteSubject() { Subject.call(this); } ConcreteSubject.prototype.operate = function() { var state = 'info'; this.notifyState(state); this.notifyObservers(this); }
3. 觀察者對象A
function ConcreteObserverA() { this.update = function(info) { console.log('A Observer'+info); }
this.updateSubject = function(subject) { console.log('A Observer object'); }
}
4. 觀察者對象B
function ConcreteObserverB() { this.update = function(info) { console.log('B Observer'+info); } this.updateSubject = function(subject) { console.log('B Observer object'); } }
5. 使用方法;
var subject = new ConcreteSubject(); var aobserver = new ConcreteObserverA(); var bobserver = new ConcreteObserverB(); subject.add(aobserver); subject.add(bobserver); subject.operate();
其餘說明
主題對象是能夠多種不一樣存在的,就是上面的媽媽叫孩子吃飯例子,一個小區,一個小村莊會有多個的母親,一個母親下會有一個或幾個的孩子;
母親是被觀察者,小孩們是觀察者,他們在等待母親主動推送消息通知他們去吃飯,可是小孩子回家的具體方式是不同的,有的是立刻跑回來,有的是慢慢吞吞回家去;
母親是一個對象類,這個對象類當發生煮飯煮熟了,就會執行operate這個方法,去通知這小孩子的觀察類對象,而後再更新本身回家去,在面向對象原則裏,類要求功能單一職責,這有助於應用狀況的擴展以及解耦;