觀察者模式

觀察者模式中有主題(Subject)和觀察者(Observer),分別對應(yīng)報社和訂閱用戶(你).觀察者模式定義了對象之間的一對多的依賴關(guān)系,這樣,當(dāng)"一"的一方狀態(tài)發(fā)生變化時,它所依賴的"多"的一方都會收到通知并且自動更新.如圖:


D3323DD0-D6DF-43CA-90C7-B0F82831EF36.png

Android開發(fā)中經(jīng)常用到:

mBtn.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
      }
});

這段代碼中 mBtn 是被觀察者, OnClickListener 是觀察者。 二者通過setOnClickListener() 方法達(dá)成訂閱關(guān)系梦裂。setOnClickListener方法使得mBtn保存了調(diào)用onClick()方法的機(jī)會告匠。至于mBtn怎么去調(diào)用onClick方法就看mBtn怎么去實現(xiàn)了,很明顯當(dāng)mBtn被點擊的時候著隆,就會去判斷是否注冊了onClick方法扰楼,如果有就調(diào)用。
總結(jié)起來就是:
(Button-> 被觀察者( Observable)旅东、OnClickListener ->觀察者(Observer)灭抑、setOnClickListener() ->訂閱(subscribe),onClick() -> 事件(event))
觀察者模式抽象出來就是: Observable.subscribe(Observer)

介紹

觀察者模式也被稱為發(fā)布-訂閱(Publish/Subscribe)模式抵代,它屬于行為型模式的一種腾节。觀察者模式定義了一種一對多的依賴關(guān)系,一個主題對象可被多個觀察者對象同時監(jiān)聽荤牍。當(dāng)這個主題對象狀態(tài)變化時案腺,會通知所有觀察者對象并作出相應(yīng)處理邏輯。

UML

950DCBF6-1D6B-40A3-9430-E75586FDA68D.png

觀察者模式定義了四種角色:抽象主題康吵、具體主題劈榨、抽象觀察者、具體觀察者晦嵌。

  1. 抽象主題(Subject):該角色是一個抽象類或接口同辣,定義了增加、刪除惭载、通知觀察者對象的方法旱函。
  2. 具體主題(ConcreteSubject):該角色繼承或?qū)崿F(xiàn)了抽象主題,定義了一個集合存入注冊過的具體觀察者對象描滔,在具體主題的內(nèi)部狀態(tài)發(fā)生改變時棒妨,給所有注冊過的觀察者發(fā)送通知。
  3. 抽象觀察者(Observer):該角色是具體觀察者的抽象類含长,定義了一個更新方法券腔。
  4. 具體觀察者(ConcrereObserver):該角色是具體的觀察者對象,在得到具體主題更改通知時更新自身的狀態(tài)拘泞。

實現(xiàn)代碼

抽象觀察者(Observer)接口
public interface Observer {
     public void update(String msg, TextView tv);
}
具體觀察者(Person)類
public class Person implements Observer {
    // 用戶名
    private String name;
    public Person(String name) {
        this.name = name;
    }
    @Override
    public void update(String msg, TextView tv) {
        tv.setText(tv.getText()+name+":"+ msg +"\n");
    }
}
抽象主題(Subject)或者說是 被觀察者 (Observerable) 接口
public interface Subject {
    /**
     * 增加觀察者
     * @param observer
     */
    public void attach(Observer observer);
    /**
     * 刪除觀察者
     * @param observer
     */
    public void detach(Observer observer);
    /**
     * 通知觀察者
     */
    public void notify(String message, TextView v);
}
具體主題(XiaosongSubject)類
public class XiaosongSubject implements Subject {
    //用于保存訂閱了小嵩的博客的用戶
    private List<Observer> mPersonList = new ArrayList<>();
    @Override
    public void attach(Observer observer) {
        mPersonList.add(observer);
    }
    @Override
    public void detach(Observer observer) {
        mPersonList.remove(observer);
    }
    @Override
    public void notify(String message, TextView tv) {
        for (Observer observer : mPersonList) {
            observer.update(message,tv);
        }
    }
}
測試代碼
E7AF9173-1647-443E-A94A-ABB2D21414CE.png

總結(jié)

在Android中纷纫,有很多場景使用了觀察者模式,比如Android的源碼里:OnClickListener田弥、ContentObserver涛酗、android.database.Observable等;還有第三方開源庫EventBus、RxJava商叹、RxAndroid等燕刻。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市剖笙,隨后出現(xiàn)的幾起案子卵洗,更是在濱河造成了極大的恐慌悯恍,老刑警劉巖晴裹,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枢舶,死亡現(xiàn)場離奇詭異肃廓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)系枪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門单料,熙熙樓的掌柜王于貴愁眉苦臉地迎上來固该,“玉大人扳躬,你說我怎么就攤上這事脆诉。” “怎么了贷币?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵击胜,是天一觀的道長。 經(jīng)常有香客問我役纹,道長偶摔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任促脉,我火速辦了婚禮辰斋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瘸味。我一直安慰自己亡呵,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布硫戈。 她就那樣靜靜地躺著,像睡著了一般下硕。 火紅的嫁衣襯著肌膚如雪丁逝。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天梭姓,我揣著相機(jī)與錄音霜幼,去河邊找鬼。 笑死誉尖,一個胖子當(dāng)著我的面吹牛罪既,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼琢感,長吁一口氣:“原來是場噩夢啊……” “哼丢间!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起驹针,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤烘挫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后柬甥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饮六,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年苛蒲,在試婚紗的時候發(fā)現(xiàn)自己被綠了卤橄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡臂外,死狀恐怖窟扑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情寄月,我是刑警寧澤辜膝,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站漾肮,受9級特大地震影響厂抖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜克懊,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一忱辅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谭溉,春花似錦墙懂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至柜与,卻和暖如春巧勤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背弄匕。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工颅悉, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人迁匠。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓剩瓶,卻偏偏與公主長得像驹溃,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子延曙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

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

  • 了解 RxJava 的應(yīng)該都知道是一個基于事務(wù)驅(qū)動的庫豌鹤,響應(yīng)式編程的典范。提到事務(wù)驅(qū)動和響應(yīng)就不得不說說搂鲫,設(shè)計模式...
    騎摩托馬斯閱讀 604評論 0 1
  • 用最簡單的一句話來理解觀察者模式就是:當(dāng)一個對象發(fā)生改變時傍药,其相關(guān)依賴對象皆得到通知并被自動更新。 關(guān)于這個圖的四...
    芒果味的你呀閱讀 1,372評論 0 9
  • 上一篇中我們了解了什么是RxJava魂仍,用一個詞來總結(jié)就是異步拐辽。這里我們來講講RxJava的異步實現(xiàn)。它是通過一種擴(kuò)...
    于闐閱讀 2,151評論 0 2
  • 前言 Android的設(shè)計模式系列文章介紹擦酌,歡迎關(guān)注俱诸,持續(xù)更新中: Android的設(shè)計模式-設(shè)計模式的六大原則一...
    四月葡萄閱讀 30,521評論 7 64
  • 一、觀察者模式的定義 定義對象間一對多的依賴關(guān)系赊舶,使得當(dāng)前對象改變了狀態(tài)睁搭,則所有依賴于它的對象都會得到通知并自動更...
    sssssss_閱讀 573評論 0 0