hello world

          隨筆 - 2, 文章 - 63, 評論 - 0, 引用 - 0
          數據加載中……

          Java_觀察者模式(Observable和Observer)

          一、觀察者模式介紹

          在Java中通過Observable類和Observer接口實現了觀察者模式。一個Observer對象監視著一個Observable對象的變化,當Observable對象發生變化時,Observer得到通知,就可以進行相應的工作。

          如果畫面A是顯示數據庫里面的數據,而畫面B修改了數據庫里面的數據,那么這時候畫面A就要重新Load。這時候就可以用到觀察者模式

          二、觀察者模式實現方法

          java.util.Observable中有兩個方法對Observer特別重要

          ①setChanged()方法

          1?????/**?
          2??????*?Sets?the?changed?flag?for?this?{@code?Observable}.?After?calling?
          3??????*?{@code?setChanged()},?{@code?hasChanged()}?will?return?{@code?true}.?
          4??????*/??
          5?????protected?void?setChanged()?{??
          6?????????changed?=?true;??
          7?????}??

          ②notifyObservers()方法 / notifyObservers(Object data)方法

          ?1?/**?
          ?2??*?If?{@code?hasChanged()}?returns?{@code?true},?calls?the?{@code?update()}?
          ?3??*?method?for?every?observer?in?the?list?of?observers?using?null?as?the?
          ?4??*?argument.?Afterwards,?calls?{@code?clearChanged()}.?
          ?5??*?<p>?
          ?6??*?Equivalent?to?calling?{@code?notifyObservers(null)}.?
          ?7??*/??
          ?8?public?void?notifyObservers()?{??
          ?9?????notifyObservers(null);??
          10?}??
          11???
          12?/**?
          13??*?If?{@code?hasChanged()}?returns?{@code?true},?calls?the?{@code?update()}?
          14??*?method?for?every?Observer?in?the?list?of?observers?using?the?specified?
          15??*?argument.?Afterwards?calls?{@code?clearChanged()}.?
          16??*?
          17??*?@param?data?
          18??*????????????the?argument?passed?to?{@code?update()}.?
          19??*/??
          20?@SuppressWarnings("unchecked")??
          21?public?void?notifyObservers(Object?data)?{??
          22?????int?size?=?0;??
          23?????Observer[]?arrays?=?null;??
          24?????synchronized?(this)?{??
          25?????????if?(hasChanged())?{??
          26?????????????clearChanged();??
          27?????????????size?=?observers.size();??
          28?????????????arrays?=?new?Observer[size];??
          29?????????????observers.toArray(arrays);??
          30?????????}??
          31?????}??
          32?????if?(arrays?!=?null)?{??
          33?????????for?(Observer?observer?:?arrays)?{??
          34?????????????observer.update(this,?data);??
          35?????????}??
          36?????}??
          37?}?


          以上兩個方法十分重要

          setChanged()方法 ——

          用來設置一個內部標志位注明數據發生了變化

          notifyObservers()方法 / notifyObservers(Object data)方法 ——

          通知所有的Observer數據發生了變化,這時所有的Observer會自動調用復寫好的update(Observable observable, Object data)方法來做一些處理(比如說畫面數據的更新)。

          我們可以看到通知Observer有兩個方法,一個無參,一個有參。那么這個參數有什么作用呢?

          其中一個作用:現在我不想通知所有的Observer,而只想其中一個指定的Observer做一些處理,那么就可以傳一個參數作為ID,然后在所有的Observer中判斷,每個Observer判斷只有接收到底參數ID是屬于自己的才做一些處理。

          當然參數還有其他作用,我只是舉了個例子。


          下面舉個例子加以說明:

          ?1?import?java.util.Observable;????
          ?2?/**?
          ?3??*?被觀察者類?
          ?4??*/??????
          ?5?public?class?SimpleObservable?extends?Observable????
          ?6?{????
          ?7????private?int?data?=?0;????
          ?8???????
          ?9????public?int?getData(){?????
          10????????return?data;????
          11????}????
          12???????
          13????public?void?setData(int?i){????
          14????????if(this.data?!=?i)?{???
          15???????????this.data?=?i;???
          16???????????setChanged();????
          17???
          18???????????//只有在setChange()被調用后,notifyObservers()才會去調用update(),否則什么都不干。??
          19???????????notifyObservers();??????
          20????????}????
          21????}????
          22?}?

          上面這個類是一個被觀察者類,它繼承了Observable類,表示這個類是可以被觀察的。

          然后在setData()方法里面,也就是數據改變的地方,來調用Observable類的setChanged()方法和notifyObservers()方法,表示數據已改變并通知所有的Observer調用它們的update()方法做一些處理。

          注意:只有在setChange()被調用后,notifyObservers()才會去調用update(),否則什么都不干。

          ?1?????/**?
          ?2??????*?觀察者類?
          ?3??????*/????????
          ?4?????public?class?SimpleObserver?implements?Observer????
          ?5?????{????
          ?6????????public?SimpleObserver(SimpleObservable?simpleObservable){????
          ?7???????????simpleObservable.addObserver(this?);????
          ?8????????}????
          ?9???????????
          10????????public?void?update(Observable?observable?,Object?data){??//?data為任意對象,用于傳遞參數??
          11???????????System.out.println(“Data?has?changed?to”?+?(SimpleObservable)observable.getData());????
          12????????}????
          13?????}???

          通過生成被觀察者(SimpleObservable類)的實例,來調用addObserver(this)方法讓觀察者(SimpleObserver類)達到觀察被觀察者(SimpleObservable類)的目的。

          然后還要復寫update()方法,做數據改變后的一些處理。

          下面可以寫一個簡單的測試類來測試一下

          ?1?public?class?SimpleTest????
          ?2?{????
          ?3????public?static?void?main(String[]?args){????
          ?4???????SimpleObservable?doc?=?new?SimpleObservable?();????
          ?5???????SimpleObserver?view?=?new?SimpleObserver?(doc);????
          ?6???????doc.setData(1);????
          ?7???????doc.setData(2);????
          ?8???????doc.setData(2);????
          ?9???????doc.setData(3);?????
          10????}????
          11?}??

          運行結果如下
          1. Data?has?changed?to?1???
          2. Data?has?changed?to?2??//第二次setData(2)時由于沒有setChange,所以update沒被調用??
          3. Data?has?changed?to?3??

          下面介紹一個Observable類的其他一些屬性和方法

          屬性 ——


          1?????//?observers是一個List,保存著所有要通知的observer。??????
          2?????List<Observer>?observers?=?new?ArrayList<Observer>();??
          3?????//?changed是一個boolean型標志位,標志著數據是否改變了。??
          4?????boolean?changed?=?false;??

          方法 ——


          ?1?????//?添加一個Observer到列表observers中??
          ?2?????public?void?addObserver(Observer?observer)?{??
          ?3?????????if?(observer?==?null)?{??
          ?4?????????????throw?new?NullPointerException();??
          ?5?????????}??
          ?6?????????synchronized?(this)?{??
          ?7?????????????if?(!observers.contains(observer))??
          ?8?????????????????observers.add(observer);??
          ?9?????????}??
          10?????}??
          11???????
          12?????//?從列表observers中刪除一個observer??
          13???????
          14?????public?synchronized?void?deleteObserver(Observer?observer)?{??
          15?????????observers.remove(observer);??
          16?????}??
          17???????
          18?????//?清空列表observers??
          19?????public?synchronized?void?deleteObservers()?{??
          20?????????observers.clear();??
          21?????}??
          22???????
          23?????//?返回列表observers中observer的個數??
          24???????
          25?????public?int?countObservers()?{??
          26?????????return?observers.size();??
          27?????}??
          28???????
          29???????
          30?????//?重置數據改變標志位為未改變??
          31?????protected?void?clearChanged()?{???
          32?????changed?=?false;??
          33?????}??
          34???????
          35?????//?將數據改變標志位設置為改變??
          36???????
          37?????protected?void?setChanged()?{???
          38?????????changed?=?true;??
          39?????}??
          40???????
          41???????
          42?????//?判斷標志位的值??
          43?????public?boolean?hasChanged()?{???
          44?????????return?changed;??
          45?????}??
          46???????
          47?????//?通知所有observer(無參)??
          48?????public?void?notifyObservers()?{??
          49?????????notifyObservers(null);??
          50?????}??
          51?????//?通知所有observer(有參)??
          52?????@SuppressWarnings("unchecked")??
          53?????public?void?notifyObservers(Object?data)?{???
          54?????????int?size?=?0;???
          55?????????Observer[]?arrays?=?null;???
          56?????????synchronized?(this)?{???
          57?????????????if?(hasChanged())?{???
          58?????????????????clearChanged();???
          59?????????????????size?=?observers.size();??
          60?????????????????arrays?=?new?Observer[size];???
          61?????????????????observers.toArray(arrays);???
          62?????????????}???
          63?????????}???
          64?????????if?(arrays?!=?null)?{???
          65?????????????for?(Observer?observer?:?arrays)?{???
          66?????????????????observer.update(this,?data);???
          67?????????????}???
          68?????????}??
          69?????}??

          注意:在Observer對象銷毀前一定要用deleteObserver將其從列表中刪除,也就是在onDestroy()方法中調用deleteObserver()方法。

          不然因為還存在對象引用的關系,Observer對象不會被垃圾收集,造成內存泄漏,并且已死的Observer仍會被通知到,有可能造成意料外的錯誤,而且隨著列表越來越大,notifyObservers操作也會越來越慢。


          下面2個工程是Observable與Observer的經典運用,是android實現的單指拖動放大圖片的操作

          兩個例子:

          http://download.csdn.net/detail/tianjf0514/4237628

          http://download.csdn.net/download/tianjf0514/4237634

          posted on 2017-07-25 10:39 聽風 閱讀(127) 評論(0)  編輯  收藏 所屬分類: JAVA

          主站蜘蛛池模板: 渑池县| 乌鲁木齐市| 景泰县| 横峰县| 淮滨县| 静宁县| 梓潼县| 卢湾区| 乐平市| 九龙坡区| 石嘴山市| 泰兴市| 莒南县| 汕头市| 光山县| 常州市| 淮北市| 龙胜| 交城县| 宿松县| 孟村| 成都市| 赤壁市| 四子王旗| 抚松县| 金堂县| 霍林郭勒市| 崇义县| 育儿| 封丘县| 呼图壁县| 渝北区| 文成县| 桐柏县| 昭通市| 朝阳区| 舟曲县| 肃南| 额敏县| 旬阳县| 龙南县|