摘要:上篇我們講解了觀察者模式的一些知識,而且自定義觀察者模式的經典代碼,傳送們設計模式走一遍觀察者模式上這篇簡單講一下自帶的觀察者模式實現代碼。注被觀察者又被稱為主題對象,目標對象。
上篇我們講解了觀察者模式的一些知識,而且自定義觀察者模式的經典代碼,(傳送們:設計模式走一遍---觀察者模式(上))
這篇簡單講一下JDK自帶的觀察者模式實現代碼。
對于觀察者模式,JDK中提供了一個Observer接口(觀察者),一個Observable類(主題對象)。
注:被觀察者又被稱為主題對象,目標對象。
具體我們來看下源碼。
1.觀察者接口
public interface Observer {
/**
* This method is called whenever the observed *object is changed.
*當被觀察者發生變化時,該方法將會被調用
* @param o the observable object.
* @param arg an argument passed to the notifyObservers
* method.
*/
void update(Observable o, Object arg);
}
該接口相當于觀察者,里面有一個update(Observable o, Object arg)方法,Observable參數是指主題對象,該參數指明該觀察者是屬于哪一個主題對象的。
arg參數可以是任意對象,假如主題對象在發送通知時,想要傳遞什么數據給觀察者,那么就可以把數據對象傳遞給arg參數。
2.主題對象類(方法有點多,我就不放英文解釋了)
//主題對象可以是接口、抽象類、具體類,我們上節說 //一般采用抽象類,不過JDK這里使用的是具體類 public class Observable { //標記主題對象的狀態是否改變 private boolean changed = false; //存放觀察者集合,之所以用Vector而不用ArrayList //主要是Vector是線程安全的 private Vectorobs; public Observable() { obs = new Vector<>(); } //添加一個觀察者 public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } //刪除一個觀察者 public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } //標記該對象的狀態是否發送了改變 protected synchronized void setChanged() { changed = true; } //指示該對象不會再發生改變,或者它已經通知了 //所有觀察者 protected synchronized void clearChanged() { changed = false; } //測試對象是否發生了改變。當且僅當在此對象最近 //調用了setChange()方法 public synchronized boolean hasChanged() { return changed; } //如果hasChanged()方法指示此對象發送了改變, //則通知所有觀察者,并且調用clearChanged()方法 //指示此對象不再改變 public void notifyObservers() { notifyObservers(null); } //與上面沒有參數的同名方法相同,只是如果這個方 //法的arg參數可以接受主題對象想要傳遞觀察者的數據對象 public void notifyObservers(Object arg) { //臨時保存所有觀察者 Object[] arrLocal; synchronized (this) { if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length-1; i>=0; i--) ((Observer)arrLocal[i]).update(this, arg); } //刪除所有觀察者 public synchronized void deleteObservers() { obs.removeAllElements(); } //返回觀察者的數量 public synchronized int countObservers() { return obs.size(); } }
該具體類Observable相當于主題對象,實現的主要功能就是當自己的狀態發送改變時,通知觀察者,觀察者再根據通知,在update方法做出相應的反應。
簡單寫個Demo測試下。
public class Test { public static void main(String[] args){ //創建一個主題對象 AnimalSubject animalSubject = new AnimalSubject(); animalSubject.addObserver(new DogObsever()); animalSubject.addObserver(new LionObsever()); //狀態發生改變 animalSubject.setChanged(); //通知觀察者 animalSubject.notifyObservers(); } } //動物主題,弄子類方便拓展主題對象功能 class AnimalSubject extends Observable{ //不過我就不新增代碼、方法了 //不覆蓋下的話,上面的測試調用不了setChange()方法 //為了方便測試,覆蓋重寫下 @Override protected synchronized void setChanged() { super.setChanged(); } } class DogObsever implements Observer{ @Override public void update(Observable o, Object arg) { System.out.println("收到通知,小狗觀察者正在做出相應處理"); } } class LionObsever implements Observer{ @Override public void update(Observable o, Object arg) { System.out.println("收到通知,獅子觀察者正在做出相應處理"); } }
打印結果
收到通知,獅子觀察者正在做出相應處理 收到通知,小狗觀察者正在做出相應處理
從上面的代碼中我們可以發現JDk內置的觀察者模式中的主題對象是一個具體類,而不是一個抽象類或接口,而且setChange()方法還被保護起來了(被定義為protected),這就意味著,要在別的類中調用該方法,那么我們必須繼承在子類中重寫覆蓋該方法。顯然,我覺得這很不友好.....
可能這也是JDK內置的觀察者模式很少被拿來使用 的原因吧,一般都是自己來自定義觀察者模式。
希望大家能夠動手寫一下這些代碼,可能會碰到一些你沒想到的問題。
完
關注公我的眾號:苦逼的碼農,獲取更多原創文章,后臺回復禮包送你一份時下熱門的資源大禮包。同時也感謝把文章介紹給更多需要的人
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77020.html
摘要:觀察者模式的別名包括發布訂閱模式模型視圖模式源監聽器模式或從屬者模式。而觀察者一般也會做出對象的響應觀察者模式屬于行為型模式觀察者模式主要解決的問題一方的狀態發生了變化,依賴于這一方的觀察者立即能收到通知。參考書籍設計模式版。 1 紅燈車過,人停;綠燈人過,車停。每天走在馬路上,到處可見紅綠燈指揮著我們什么時候可以過馬路,什么時候不能過馬路。無論是人還是車,都時刻關注著紅綠燈的狀態,一...
摘要:在國內,個人還是不推薦使用,訪問速度有所影響,而且其還是一個商業產品。今天利用最簡便的步,走一遍代碼集成和來使用。代碼簡單創建監聽我們在后端添加一個被創建的事件,并繼承。 showImg(https://segmentfault.com/img/remote/1460000015801244?w=904&h=241); 先飚幾句英文,說說 Laravel Echo 的作用: One o...
摘要:今天就說說移動測試中最重要的兩個方向。自動化測試完全不同于手游自動化測試手機和手游的開發技術不同,這導致了兩者的自動化測試技術是截然不同的。手游和的第二個玩法不同在于探索性。 隨著智能設備的普及和移動互聯網的興起,各家互聯網巨頭紛紛在往移動端布局和轉型,同時初創的移動互聯網公司也都盯著這個市場希望分一杯羹。在這個大環境下,互聯網的重心已經慢慢從Web端轉向了移動端,而移動端的軟件測試也...
閱讀 2817·2021-11-24 09:39
閱讀 3387·2021-11-19 09:40
閱讀 2257·2021-11-17 09:33
閱讀 3749·2021-10-08 10:04
閱讀 3037·2021-09-26 09:55
閱讀 1663·2021-09-22 15:26
閱讀 927·2021-09-10 10:51
閱讀 3124·2019-08-30 15:44