設(shè)計模式之觀察者模式

1.觀察者模式簡介

觀察者模式是一種一對多的依賴關(guān)系咆课,讓多個觀察者對象同時監(jiān)聽某一個主題對象锥余,當這個主題對象發(fā)生改變的時候,會通知 所有的觀察者對象张症,讓他們可以及時的自動更新检疫。

觀察者中的角色:

  • Subject:抽象主題(抽象被觀察者)讶请,抽象主題角色把所有觀察者對象保存在一個集合里,每個主題都可以有任意數(shù)量的觀察者屎媳,抽象主題提供一個接口夺溢,可以增加和刪除觀察者對象。
  • ConcreteSubject:具體主題(具體被觀察者)烛谊,該角色將有關(guān)狀態(tài)存入具體觀察者對象风响,在具體主題的內(nèi)部狀態(tài)發(fā)生改變時,給所有注冊過的觀察者發(fā)送通知丹禀。
  • Observer:抽象觀察者状勤,是觀察者者的抽象類,它定義了一個更新接口双泪,使得在得到主題更改通知時更新自己持搜。
  • ConcrereObserver:具體觀察者,實現(xiàn)抽象觀察者定義的更新接口焙矛,以便在得到主題更改通知時更新自身的狀態(tài)朵诫。

2.觀察者模式簡單實現(xiàn)

抽象觀察者(Observer)

里面定義了一個更新的方法

public interface Observer {
    public void update(String message);
}

具體觀察者(ConcrereObserver)

微信用戶是觀察者,里面實現(xiàn)了更新的方法

public class WeixinUser implements Observer {

    private String name;

    public WeixinUser(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {

    }
}

抽象被觀察者(Subject)

抽象主題薄扁,提供了attach剪返、detach、notify三個方法

public interface Subject {

    /**
     * 增加訂閱者
     *
     * @param observer
     */
    public void attach(Observer observer);

    /**
     * 刪除訂閱者
     *
     * @param observer
     */
    public void detach(Observer observer);

    /**
     * 通知訂閱者
     *
     * @param message
     */
    public void notify(String message);
}

具體被觀察者(ConcreteSubject)

微信公眾號是具體主題(具體被觀察者)邓梅,里面存儲了訂閱該公眾號的微信用戶脱盲,并實現(xiàn)了抽象主題中的方法

public class SubscriptionSubject implements Subject {

    //存儲觀察者集合
    private List<Observer> weixinUserlist  = new ArrayList<>();

    @Override
    public void attach(Observer observer) {
       weixinUserlist.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        weixinUserlist .remove(observer);
    }

    @Override
    public void notify(String message) {
        for (Observer observer : weixinUserlist ) {
            observer.update(message);
        }
    }
}

客戶端調(diào)用

public class Client {
    public static void main(String[] args) {
        SubscriptionSubject mSubscriptionSubject = new SubscriptionSubject();
        //創(chuàng)建微信用戶
        WeixinUser user1 = new WeixinUser("楊影楓");
        WeixinUser user2 = new WeixinUser("月眉兒");
        WeixinUser user3 = new WeixinUser("紫軒");
        //訂閱公眾號
        mSubscriptionSubject.attach(user1);
        mSubscriptionSubject.attach(user2);
        mSubscriptionSubject.attach(user3);
        //公眾號更新發(fā)出消息給訂閱的微信用戶
        mSubscriptionSubject.notify("劉望舒的專欄更新了");
    }
}

3.使用觀察者模式的場景和優(yōu)缺點

使用場景

  • 關(guān)聯(lián)行為場景,需要注意的是日缨,關(guān)聯(lián)行為是可拆分的钱反,而不是“組合”關(guān)系。
  • 事件多級觸發(fā)場景匣距。
  • 跨系統(tǒng)的消息交換場景面哥,如消息隊列、事件總線的處理機制毅待。

優(yōu)點

解除耦合码倦,讓耦合的雙方都依賴于抽象棺蛛,從而使得各自的變換都不會影響另一邊的變換。

缺點

在應用觀察者模式時需要考慮一下開發(fā)效率和運行效率的問題,程序中包括一個被觀察者莲组、多個觀察者,開發(fā)窃植、調(diào)試等內(nèi)容會比較復雜永罚,而且在Java中消息的通知一般是順序執(zhí)行,那么一個觀察者卡頓盅蝗,會影響整體的執(zhí)行效率鳖链,在這種情況下,一般會采用異步實現(xiàn)墩莫。

4.Android中的觀察者模式

android源碼中也有很多使用了觀察者模式芙委,比如OnClickListener、ContentObserver贼穆、android.database.Observable等题山;還有組件通訊庫RxJava、RxAndroid故痊、EventBus.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末顶瞳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子愕秫,更是在濱河造成了極大的恐慌慨菱,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件戴甩,死亡現(xiàn)場離奇詭異符喝,居然都是意外死亡,警方通過查閱死者的電腦和手機甜孤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進店門协饲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畏腕,“玉大人,你說我怎么就攤上這事茉稠∶柘冢” “怎么了?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵而线,是天一觀的道長铭污。 經(jīng)常有香客問我,道長膀篮,這世上最難降的妖魔是什么嘹狞? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮誓竿,結(jié)果婚禮上磅网,老公的妹妹穿的比我還像新娘。我一直安慰自己烤黍,他們只是感情好知市,可當我...
    茶點故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著速蕊,像睡著了一般嫂丙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上规哲,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天跟啤,我揣著相機與錄音,去河邊找鬼唉锌。 笑死隅肥,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的袄简。 我是一名探鬼主播腥放,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼绿语!你這毒婦竟也來了秃症?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤吕粹,失蹤者是張志新(化名)和其女友劉穎种柑,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匹耕,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡聚请,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了稳其。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驶赏。...
    茶點故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡炸卑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出母市,到底是詐尸還是另有隱情矾兜,我是刑警寧澤,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布患久,位于F島的核電站,受9級特大地震影響浑槽,放射性物質(zhì)發(fā)生泄漏蒋失。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一桐玻、第九天 我趴在偏房一處隱蔽的房頂上張望篙挽。 院中可真熱鬧,春花似錦镊靴、人聲如沸铣卡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽煮落。三九已至,卻和暖如春踊谋,著一層夾襖步出監(jiān)牢的瞬間蝉仇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工殖蚕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留轿衔,地道東北人。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓睦疫,卻偏偏與公主長得像害驹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蛤育,可洞房花燭夜當晚...
    茶點故事閱讀 45,446評論 2 359

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