【觀察者模式】
也叫作發布/訂閱模式,使用較為頻繁。
定義了對象間一種一對多的依賴關系,當一個對象改變狀態時,則所有依賴于它的對象都會得到通知并被自動更新。
觀察者模式由以下幾個角色組成:
* Subject 被觀察者
定義被觀察者必須實現的職責,他必須能夠動態地增阿基、取消觀察者。一般是抽象類或實現類,僅僅完成作為被觀察者必須實現的職責:管理觀察者+通知觀察者。
* ConcreteSubject具體的被觀察者
定義觀察者自己的業務邏輯,同時定義對哪些事件進行通知。
* Observer 觀察者
觀察者接收到消息后,即進行update(更新方法)操作,對接收到的消息進行處理。
* ConcreteObserver具體的觀察者
每個具體觀察者在接受到消息后的處理反應是不一樣的,各個觀察者有自己的處理邏輯。
?
【觀察者模式 例子】
package com.Higgin.Observer; import java.util.ArrayList; import java.util.List;/*** 電視觀眾接口 */ interface Viewer{public void feel(String show); } /*** 年輕觀眾*/ class YongViewer implements Viewer{@Overridepublic void feel(String show) {System.out.println("年輕人:感覺《"+show+"》很棒!");} } /*** 老年觀眾*/ class OldViewer implements Viewer{@Overridepublic void feel(String show) {System.out.println("老年人:感覺《"+show+"》一般!");} } /*** 抽象電視節目*/ abstract class TVProgrammer{//用來保存 注冊的電視觀眾對象private List<Viewer> viewers=new ArrayList<Viewer>();//注冊一個電視觀眾public void attach(Viewer v){this.viewers.add(v);}//刪除一個電視觀眾public void detach(Viewer v){this.viewers.remove(v);}//通知所有注冊的電視觀眾public void notifyViewers(String show){for(Viewer v:viewers){v.feel(show);}} }/*** 具體的娛樂電視節目*/ class HappyTVProgrammer extends TVProgrammer{//切換不同的娛樂節目public void change(String newShow){super.notifyViewers(newShow); //調用父類的通知方法 } }public class TestObserver {public static void main(String[] args) {Viewer yong=new YongViewer(); //一個年輕觀眾Viewer old=new OldViewer(); //一個老年觀眾HappyTVProgrammer tvp=new HappyTVProgrammer(); //娛樂電視節目tvp.attach(yong); //注冊一個年輕人tvp.attach(old); //注冊一個老年人tvp.notifyViewers("極限挑戰");System.out.println("=============================");tvp.detach(old); //老人不愛看,解除tvp.change("奔跑吧,兄弟!");} }
【運行結果】
?
【觀察者模式 優點】
* 觀察者和被觀察者之間是抽象耦合的
不管是增加觀察者還是被觀察者都非常容易,而且在java中已經實現了抽象層級的定義,在系統擴展方面應用良好。
* 建立了一套觸發機制
根據單一職責原則,每個類的職責是單一的,如A事件觸發B事件,B事件觸發C事件...這是一個觸發機制,形成一個觸發鏈,觀察者模式可以實現這里的鏈條形式。
【觀察者模式 缺點】
要考慮開發效率和運行效率的問題,一個被觀察者,多個觀察者,開發和調試較為復雜,而且在JAVA中消息通知默認是順序執行的,一個觀察者卡殼,會影響整體的執行效率。這種情況一般會采用異步的方式。
【觀察者模式 使用場景】
* 關聯行為場景,注意關聯行為是可拆分的,而不是“組合”關系。
* 事件多級觸發場景。
* 跨系統的消息交換場景。
?