d_3. 觀察者模式

1术幔、模式定義

  • 觀察者模式是對(duì)象的行為模式侄柔,又叫發(fā)布-訂閱(Publish/Subscribe)模式既们、模型-視圖(Model/View)模式仲吏、源-監(jiān)聽器(Source/Listener)模式或從屬者(Dependents)模式不铆。
  • 觀察者模式定義了一種一對(duì)多的依賴關(guān)系蝌焚,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)上發(fā)生變化時(shí)誓斥,會(huì)通知所有觀察者對(duì)象只洒,使它們能夠自動(dòng)更新自己。
  • 被觀察者 訂閱 觀察者 => Observable Subscribe Observer

2劳坑、代碼實(shí)現(xiàn)

// 觀察者接口
public interface Observer {
     void update(Observable observable, Object object);
}

// 具體的觀察者
public class PoliceObserver implements Observer {

    @Override
    public void update(Observable o, Object arg) {
        System.out.print("狀態(tài)發(fā)生改變:");
        ((ThiefObservable) o).capture();
    }
}

// 被觀察者管理類
public class Observable{

    public Vector<Observer> observers;

    public Observable() {
        observers = new Vector<Observer>();
    }

    public void addObserver(Observer observer) {
        if (observers == null) return;
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        if (observers == null && observers.size() <= 0) {
            return;
        }
        observers.remove(observer);
    }

    public void notifyObservables() {
        notifyObservables(null);
    }

    public void notifyObservables(Object object) {
        if (observers == null && observers.size() <= 0) {
            return;
        }
        for (Observer observer : observers) {
            observer.update(this, object);
        }
    }
}

// 具體的被觀察者
public class ThiefObservable extends Observable {

    public void steal() {
        System.out.println("小偷準(zhǔn)備偷東西了");
        notifyObservables();
    }

    public void capture() {
        System.out.println("小偷被抓");
    }
}

public class TestDemo {

    public static void main(String[] args) {
        // 創(chuàng)建被觀察者對(duì)象
        ThiefObservable thiefObservable = new ThiefObservable();
        // 創(chuàng)建觀察者對(duì)象毕谴,并將被觀察者對(duì)象登記
        PoliceObserver policeObserver = new PoliceObserver();
        // 被觀察者訂閱觀察者
        thiefObservable.addObserver(policeObserver);
        // 被觀察者執(zhí)行某些操作
        thiefObservable.steal();
        // 取消被觀察者與觀察者之間的訂閱關(guān)系
        thiefObservable.removeObserver(policeObserver);
        // 被觀察者執(zhí)行某些操作
        thiefObservable.steal();
    }
}
=====================================================
運(yùn)行結(jié)果:
小偷準(zhǔn)備偷東西了
狀態(tài)發(fā)生改變:小偷被抓
小偷準(zhǔn)備偷東西了
=====================================================

3、常見使用場(chǎng)景

  • java.util庫提供了一個(gè)Observable類以及一個(gè)Observer接口距芬。
  • RxJava涝开。

4、優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):(1)觀察者模式符合松耦合框仔。(2)觀察者不會(huì)因主動(dòng)獲取通知而錯(cuò)過狀態(tài)舀武。(3)表示層和數(shù)據(jù)邏輯層的分離。
  • 缺點(diǎn):(1)通知觀察者的時(shí)間花費(fèi)离斩。(2)多個(gè)被通知者間循環(huán)可能發(fā)生死鎖银舱。(3)主題持有觀察者的引用,如果未正常處理從主題中刪除觀察者跛梗,會(huì)導(dǎo)致觀察者無法被回收寻馏。

5、參考資料

  • java.util庫中的Observable類和Observer接口源碼
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末核偿,一起剝皮案震驚了整個(gè)濱河市诚欠,隨后出現(xiàn)的幾起案子玄捕,更是在濱河造成了極大的恐慌蘸秘,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件方仿,死亡現(xiàn)場(chǎng)離奇詭異蝗羊,居然都是意外死亡藏澳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門耀找,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翔悠,“玉大人,你說我怎么就攤上這事野芒⌒畛睿” “怎么了?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵狞悲,是天一觀的道長(zhǎng)撮抓。 經(jīng)常有香客問我,道長(zhǎng)摇锋,這世上最難降的妖魔是什么丹拯? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任站超,我火速辦了婚禮,結(jié)果婚禮上乖酬,老公的妹妹穿的比我還像新娘死相。我一直安慰自己,他們只是感情好咬像,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布算撮。 她就那樣靜靜地躺著,像睡著了一般县昂。 火紅的嫁衣襯著肌膚如雪肮柜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天七芭,我揣著相機(jī)與錄音素挽,去河邊找鬼。 笑死狸驳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缩赛。 我是一名探鬼主播耙箍,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼酥馍!你這毒婦竟也來了辩昆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤旨袒,失蹤者是張志新(化名)和其女友劉穎汁针,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體砚尽,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡施无,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了必孤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猾骡。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖敷搪,靈堂內(nèi)的尸體忽然破棺而出兴想,到底是詐尸還是另有隱情,我是刑警寧澤赡勘,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布嫂便,位于F島的核電站,受9級(jí)特大地震影響闸与,放射性物質(zhì)發(fā)生泄漏毙替。R本人自食惡果不足惜曼振,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蔚龙。 院中可真熱鬧冰评,春花似錦、人聲如沸木羹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坑填。三九已至抛人,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間脐瑰,已是汗流浹背妖枚。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留苍在,地道東北人绝页。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像寂恬,于是被迫代替她去往敵國(guó)和親续誉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容