您好,登錄后才能下訂單哦!
這篇文章主要講解了“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)注!
免責(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)容。