<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    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 聽風 閱讀(123) 評論(0)  編輯  收藏 所屬分類: JAVA

    主站蜘蛛池模板: 噜噜噜亚洲色成人网站∨| 91国内免费在线视频| 84pao强力永久免费高清| 亚洲AV永久纯肉无码精品动漫| 一级中文字幕乱码免费| 国产精品视_精品国产免费| 香蕉视频免费在线| 亚洲一区二区三区国产精品| 亚洲国产高清在线精品一区| 在线播放免费人成视频网站| 久久精品国产亚洲5555| 亚洲国产精品久久久久秋霞小| 久久永久免费人妻精品| 久久精品国产精品亚洲毛片| 日韩视频在线精品视频免费观看| 亚洲熟妇丰满多毛XXXX| 边摸边吃奶边做爽免费视频网站 | 中文字幕亚洲第一在线| 亚洲w码欧洲s码免费| 国产成A人亚洲精V品无码| 97精品免费视频| 亚洲精品无码专区久久| 免费三级毛片电影片| 亚洲精品av无码喷奶水糖心| 亚洲福利精品一区二区三区| 国内精品久久久久影院免费| JLZZJLZZ亚洲乱熟无码| 一区二区在线免费观看| 亚洲色大成WWW亚洲女子| 亚洲人成网站18禁止一区| 一级毛片免费观看| 亚洲JLZZJLZZ少妇| 亚洲国产精品高清久久久| 美女被免费喷白浆视频| 无码免费又爽又高潮喷水的视频 | 女人18毛片a级毛片免费| 一级全免费视频播放| 亚洲国产精品无码久久久| 亚洲VA综合VA国产产VA中| 久久免费看黄a级毛片| 亚洲欧洲日产国产最新|