溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

java的監(jiān)聽者模式和觀察者分別有什么作用

發(fā)布時間:2021-06-24 11:30:35 來源:億速云 閱讀:312 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要講解了“java的監(jiān)聽者模式和觀察者分別有什么作用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“java的監(jiān)聽者模式和觀察者分別有什么作用”吧!


一、java.util.Observer —— 觀察者接口 對應(yīng): 
java.util.Observable ——受查者根類 

二、java.util.EventListener —— 事件監(jiān)聽/處理接口 對應(yīng): 
java.util.EventObject —— 事件(狀態(tài))對象根類 

研究了一下發(fā)現(xiàn)這兩種接口的目的、功能其實是一樣的(僅在事件模型的結(jié)構(gòu)上有些許差異),先看EventListener事件監(jiān)聽器模式: 
 

// https://blog.csdn.net/sbvfhp/article/details/8763896
// java設(shè)計模式--觀察者模式和事件監(jiān)聽器模式

//首要定義事件源對象(事件源相當(dāng)于單擊按鈕事件當(dāng)中的按鈕對象、屬于被監(jiān)聽者)
public class DemoSource {   
    private Vector repository = new Vector();//監(jiān)聽自己的監(jiān)聽器隊列   
    public DemoSource(){}   
    public void addDemoListener(DemoListener dl) {   
           repository.addElement(dl);   
    }  
    public void notifyDemoEvent() {//通知所有的監(jiān)聽器   
           Enumeration enum = repository.elements();   
           while(enum.hasMoreElements()) {   
                   DemoListener dl = (DemoListener)enum.nextElement();   
                 dl.handleEvent(new DemoEvent(this));   
           }   
    }  
}

// 其次定義事件(狀態(tài))對象(該事件對象包裝了事件源對象、作為參數(shù)傳遞給監(jiān)聽器、很薄的一層包裝類)
public class DemoEvent extends java.util.EventObject {   
    public DemoEvent(Object source) {   
      super(source);//source—事件源對象—如在界面上發(fā)生的點擊按鈕事件中的按鈕   
       //所有 Event 在構(gòu)造時都引用了對象 "source",在邏輯上認(rèn)為該對象是最初發(fā)生有關(guān) Event 的對象  
    }   
    public void say() {   
           System.out.println("This is say method...");   
    }   
}  

//最后定義我們的事件偵聽器接口如下:
public interface DemoListener extends java.util.EventListener {   
    //EventListener是所有事件偵聽器接口必須擴(kuò)展的標(biāo)記接口、因為它是無內(nèi)容的標(biāo)記接口、   
    //所以事件處理方法由我們自己聲明如下:   
    public void handleEvent(DemoEvent dm);   
}  

//定義具體的事件監(jiān)聽器:   
public class DemoListener1 implements DemoListener {   
       public void handleEvent(DemoEvent de) {   
              System.out.println("Inside listener1...");   
              de.say();//回調(diào)   
       }   
}   
  
public class TestDemo {   
    DemoSource ds;   
  
    public TestDemo(){   
      try{   
                 ds = new DemoSource();   
  
                 //將監(jiān)聽器在事件源對象中登記:   
                 DemoListener1 l1 = new DemoListener1();   
                 ds.addDemoListener(l1);   
                 ds.addDemoListener(new DemoListener() {   
                            public void handleEvent(DemoEvent event) {   
                                      System.out.println("Method come from 匿名類...");   
                            }   
                 });   
  
  
                 ds.notifyDemoEvent();//觸發(fā)事件、通知監(jiān)聽器   
  
           }catch(Exception ex) {ex.printStackTrace();}   
    }   
  
    public static void main(String args[]) {   
           new TestDemo();   
    }   
}

再看Observer觀察者模式: 
Observer和EventListener的區(qū)別僅僅在于它提前聲明了事件處理方法: 
update(Observable o, Object arg) 
Observer模式當(dāng)中不存在對應(yīng)EventObject的角色,Observable被觀察者就兼具了source事件源和EventObject事件對象兩種角色,模型更簡潔。 
Observable被觀察者根類就持有了觀察者隊列,也定義了類似notifyDemoEvent()的notifyObservers()方法... 

除了結(jié)構(gòu)有差異外實在看不出Observer觀察者模式和EventListener事件監(jiān)聽/處理模式的不一樣!請教二者還有什么差異嗎? 

回復(fù): 

也不能這么說 
我看了一下Observer、Observable的jdk源碼,Observer接口沒什么可說的僅僅是聲明了一個update方法而已,相當(dāng)于我在interface DemoListener extends java.util.EventListener接口中定義的:handleEvent方法。 
為什么聲明呢?最主要的是Observer模式比較EventListener的不同之處還在于將大部分工作收歸Observable根類完成。 
我又看了看Observable根類,雖然代碼也很短小但是比較精悍,至少要我自己寫考慮不了這么全面。好比java2集合,我們自己也能做些hashmap、arraylist、棧、隊但是可靠性應(yīng)該是比不上jdk提供的。 

總結(jié)一下Observer模式和EventListener的主要不同之處: 

一、模型結(jié)構(gòu)不同:EventListener是傳統(tǒng)的c/s界面事件模型,分事件源和事件(狀態(tài))角色,事件源要經(jīng)過事件的包裝、成為事件的屬性之一再傳遞給事件監(jiān)聽/處理者,這個事件監(jiān)聽者就相當(dāng)于觀察者。我記得好像VB或C#也是這種模型...而Observer模式的模型就簡潔多了,沒有分事件源和事件,二者合二為一為一個角色:被觀察者,從字面語義上也應(yīng)該這樣,另一個是觀察者角色。 

二、就是我上面說的Observer模式比較EventListener的不同之處還在于將大部分工作收歸Observable根類實現(xiàn)了、包括定義監(jiān)聽者隊列、通知方法都實現(xiàn)了,我們只要繼承、調(diào)用和傳值就行了。 

現(xiàn)在想想可能是EventListener監(jiān)聽機(jī)制是從c/s時代就延續(xù)下來的,而Observer模式則是和iterator迭代器模式同樣被整合進(jìn)jdk的,所以現(xiàn)在這兩種功用存在交叉的api會同時存在。 

也貼出來Observer模式演示代碼來對比

//觀察者   
class Watcher implements java.util.Observer {   
  public void 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" );   
                }   
        }   
}   
};   
  
//演示   
public class ObserverDemo {   
    public static void main(String[] args) {   
        BeingWatched beingWatched = new BeingWatched();//受查者   
        Watcher watcher = new Watcher();//觀察者   
        beingWatched.addObserver(watcher);   
        beingWatched.counter(10);   
    }   
}

回復(fù): 
查閱了一些相關(guān)的東東 
原來這兩種api可以說都是基于:訂閱-發(fā)布模式的事件/消息通知模式,二者應(yīng)該都算是“推”方式吧,就是被監(jiān)控者將消息通知給所有監(jiān)控者。 
1、訂閱:Observable.addObserver; 
事件源.addDemoListener(這個方法是自己定義的)。 

2、發(fā)布:Observable需要兩步:setChanged()、notifyObservers(newValue); 
事件源.notifyDemoEvent()(這個方法也是自己定義的)。 

有人說Observer是設(shè)計模式中的皇后,很多系統(tǒng)級實現(xiàn)都是這種方式,我覺得是不是搞混了,因為我看java.util.Observer的api沒什么下級接口或?qū)崿F(xiàn)類。 
反倒是相似的java.util.EventListener有大量下級接口和實現(xiàn)類,著名的包括: 
java.beans.PropertyChangeListener 
javax.servlet.http.HttpSessionListener... 
以及java界面api里的很多... 
這么看EventListener比Observer應(yīng)用多得多,我猜想是否是因為EventListener的限制較少、沒有規(guī)定事件處理方法名、比如HttpSessionListener就根據(jù)自己的應(yīng)用領(lǐng)域定義事件處理方法: 
sessionCreated(HttpSessionEvent se) 和 
sessionDestroyed(HttpSessionEvent se) 

如果用Observer就只能叫update了。

個人理解,就是通過組合的方式來進(jìn)行耦合,盡量沒有用繼承;

感謝各位的閱讀,以上就是“java的監(jiān)聽者模式和觀察者分別有什么作用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對java的監(jiān)聽者模式和觀察者分別有什么作用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI