1. 程式人生 > >7設計模式 之 觀察者 和監聽器的區別

7設計模式 之 觀察者 和監聽器的區別

GOF設計模式中有一種叫做觀察者模式(Observer),屬於行為型模式。又叫釋出-訂閱(Publish/Subscribe)模式、模型-檢視 (Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某一個主題物件。這個 主題物件在狀態上發生變化時,會通知所有觀察者物件,使它們能夠自動更新自己。http://zoroeye.iteye.com/blog/2100318

觀察者模式被稱為是模式中的皇后,而且java jdk也對它做了實現,可見該設計模式的重要位置。在圖形化設計的軟體中,為了實現檢視和事件處理的分離,大多都採用了 Observer模式,比如java的Swing。現實的應用系統中也有好多應用,比如spring框架的初始化會觸發很多事件,監聽者可以根據自己訂閱的事件作出自己的反應。 


jdk不僅提供了Observable類、Observer介面支援觀察者模式,而且也提供了EventObject類、EventListener介面來支援事件監聽模式,雖然兩者屬於同一型別模式,都屬於回撥機制,主動推送訊息,但使用場景有些區別。 

1. 事件-監聽機制
事件源經過事件的封裝傳給監聽器,當事件源觸發事件後,監聽器接收到事件物件可以回撥事件的方法。 


2. 觀察者模式
觀察者(Observer)相當於事件監聽者(監聽器),被觀察者(Observable)相當於事件源和事件,執行邏輯時通知observer即可觸發oberver的update,同時可傳被觀察者和引數。簡化了事件-監聽模式的實現。 



3.對比

(1) 從uml圖上也可以看出,Observer的實現相對簡單,event-listener需要實現三個角色,observer-observable需要實現兩個角色。 

(2)Observable的api已經把對觀察者的註冊,刪除,監聽者佇列、通知方法 都實現等定義好了,而且是執行緒安全的。而event-listener需要使用者自己實現。 

(3)兩者都需要自己定義並實現觸發事件的通知。但Observable需要注意要在通知Observer之前呼叫jdk提供的setChanged()。 

(4)event-listener是傳統的c/s介面事件模型,分事件源和事件(狀態)角色,事件源要經過事件的包裝、成為事件的屬性之一再傳遞給事件監聽/處理者,這個事件監聽者就相當於觀察者。Observer更簡潔一些。兩者在思想上是統一的,很多框架仍然使用了event-listener模式,比如spring框架的ApplicationEvent,ApplicationListener

基於jdk 的介面實現的觀察者模式

  1. //觀察者 
  2. class Watcher implements java.util.Observer {   
  3. publicvoid update(java.util.Observable obj, Object arg) {   
  4.     System.out.println("Update() called, count is "
  5.                                 + ((Integer) arg).intValue());   
  6. }   
  7. }   
  8. //被觀察者 
  9. class BeingWatched extends java.util.Observable {   
  10. void counter(int period) {   
  11. for(; period>=0; period-- ) {   
  12.                 setChanged();   
  13.                 notifyObservers(new Integer(period));   
  14. try {   
  15.                         Thread.sleep(100);   
  16.                 } catch( InterruptedException e) {   
  17.                   System.out.println("Sleep interrupeted" );   
  18.                 }   
  19.         }   
  20. }   
  21. };   
  22. //演示 
  23. publicclass ObserverDemo {   
  24. publicstaticvoid main(String[] args) {   
  25.         BeingWatched beingWatched = new BeingWatched();//受查者 
  26.         Watcher watcher = new Watcher();//觀察者 
  27.         beingWatched.addObserver(watcher);   
  28.         beingWatched.counter(10);   
  29.     }   
  30. }