觀察者<Observer>模式(有時又被稱爲發佈-訂閱<Publish/Subscribe>模式、模型-視圖<Model/View>模式、源-收聽者<Source/Listener>模式或從屬者<Dependents>模式)是軟件設計模式的一種。在此種模式中,一個目標物件管理全部相依於它的觀察者物件,而且在它自己的狀態改變時主動發出通知。這一般透過呼叫各觀察者所提供的方法來實現。此種模式一般被用來實做事件處理系統
java
Subject(被觀察的對象接口) 設計模式
規定ConcreteSubject的統一接口;this
每一個Subject能夠有多個Observer;spa
ConcreteSubject(具體被觀察對象)設計
維護對全部具體觀察者的引用的列表;code
狀態發生變化時會發送通知給全部註冊的觀察者。server
Observer(觀察者接口)對象
規定ConcreteObserver的統一接口;繼承
定義了一個update()方法,在被觀察對象狀態改變時會被調用。接口
ConcreteObserver(具體觀察者)
維護一個對ConcreteSubject的引用;
特定狀態與ConcreteSubject同步;
實現Observer接口,經過update()方法接收ConcreteSubject的通知。
模式的應用場景和優缺點:
觀察者模式的應用場景:
1、對一個對象狀態的更新,須要其餘對象同步更新,並且其餘對象的數量動態可變。
2、對象僅須要將本身的更新通知給其餘對象而不須要知道其餘對象的細節。
觀察者模式的優勢:
1、Subject和Observer之間是鬆偶合的,分別能夠各自獨立改變。
2、Subject在發送廣播通知的時候,無須指定具體的Observer,Observer能夠本身決定是否要訂閱Subject的通知。
3、遵照大部分GRASP原則和經常使用設計原則,高內聚、低偶合。
觀察者模式的缺陷:
1、鬆偶合致使代碼關係不明顯,有時可能難以理解。(廢話)
2、若是一個Subject被大量Observer訂閱的話,在廣播通知的時候可能會有效率問題。(畢竟只是簡單的遍歷)
簡單實現觀察者模式
package designpattern; import java.util.Vector; /** * @author lei 2011-10-18 * 觀察者<Observer>模式( * 稱爲 * 發佈-訂閱<Publish/Subscribe>模式、 * 模型-視圖<Model/View>模式、 * 源-收聽者<Source/Listener>模式或 * 從屬者<Dependents>模式) * 是軟件設計模式的一種。在此種模式中,一個目標物件管理全部相依於它的觀察者物件, * 而且在它自己的狀態改變時主動發出通知。這一般透過呼叫各觀察者所提供的方法來實現。 * 此種模式一般被用來實做事件處理系統 */ public class ObserverTest { public static void main(String[] args) { //新建一個被觀察者對象,繼承了MyObserver,表明是可觀察對象,其保存了觀察者的信息,及觸發觀察者作出反映 Subject subject = new Subject(); //添加觀察者 subject.addObserver(new MailServer()); //被觀察對象執行方法,同時觸發觀察者動做 subject.doSomething(); } } //觀察者接口,定義了觀察者統一的方法 interface MyObserver { public void update(MyObservable o, Object arg); } //可觀察對象類,定義了觀察者及是否發生改變 class MyObservable { protected boolean change; //保存通知者 protected Vector<MyObserver> observers; MyObservable() { observers = new Vector<MyObserver>(); } public void notifyObservers() { notifyObservers(null); } public void romoveObservers(MyObserver obServer) { observers.remove(obServer); } public void romoveAllObservers() { observers.removeAllElements(); } //通知觀察者發生改變,並執行動做 public void notifyObservers(Object arg) { Object[] arrays = null; //同步可觀察者對象,同時清除改變 synchronized (this) { if (!change) return; arrays = observers.toArray(); clearChange(); } //通知觀察者不須要同步 for (Object obServer : arrays) { ((MyObserver) obServer).update(this, arg); } } protected synchronized void addObserver(MyObserver obServer) { observers.add(obServer); } protected synchronized void setChanged() { change = true; } protected synchronized void clearChange() { change = false; } protected synchronized boolean hasChanged() { return change; } } //通知者 class MailServer implements MyObserver { public void update(MyObservable o, Object arg) { System.out.println("send mail!"); } } //被觀察者 class Subject extends MyObservable { //執行時,同時通知觀察者 public void doSomething() { System.out.println("do something!"); setChanged(); notifyObservers(); } }