7設計模式 之 觀察者 和監聽器的區別
阿新 • • 發佈:2019-01-24
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()。
觀察者模式被稱為是模式中的皇后,而且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 的介面實現的觀察者模式
- //觀察者
- class Watcher implements java.util.Observer {
- publicvoid update(java.util.Observable obj, Object arg) {
- System.out.println("Update() called, count is "
- + ((Integer) arg).intValue());
- }
- }
- //被觀察者
- class BeingWatched extends java.util.Observable {
- void counter(int period) {
- for(; period>=0; period-- ) {
- setChanged();
- notifyObservers(new Integer(period));
- try {
- Thread.sleep(100);
- } catch( InterruptedException e) {
- System.out.println("Sleep interrupeted" );
- }
- }
- }
- };
- //演示
- publicclass ObserverDemo {
- publicstaticvoid main(String[] args) {
- BeingWatched beingWatched = new BeingWatched();//受查者
- Watcher watcher = new Watcher();//觀察者
- beingWatched.addObserver(watcher);
- beingWatched.counter(10);
- }
- }