Android 觀察者模式

Android 23種設(shè)計(jì)模式

前言

觀察者模式是我們使用率比較高的一種模式了涧狮。這類(lèi)文章網(wǎng)上也不少这嚣,通過(guò)本文我會(huì)讓你徹底理解并記住什么事觀察者模式。觀察者模式使用率之所以比較高,是因?yàn)樗贏ndroid中能達(dá)到一個(gè)十分明顯的解耦效果。讓觀察者和被觀察者邏輯分開(kāi)浪默。使得UI層和業(yè)務(wù)邏輯清晰。更加利于我們拓展代碼缀匕。

觀察者模式定義

定義一個(gè)被觀察者和多個(gè)觀察者纳决,每當(dāng)被觀察者變化,所有觀察者都會(huì)得到通知乡小。

理解重點(diǎn)

觀察者模式核心就一個(gè)點(diǎn)阔加,記住這個(gè)點(diǎn)你就能理解并記憶。要點(diǎn):用一個(gè)list把觀察者保存起來(lái)满钟,并提供add和remove觀察者胜榔,在被觀察者變化的時(shí)候就遍歷并調(diào)用list里觀察者的方法。核心就是一個(gè)list遍歷
下面我將用兩個(gè)例子來(lái)具體說(shuō)明觀察者模式湃番。例一是JDK自帶的接口夭织,例二是自己寫(xiě)觀察者模式

例子一

先來(lái)一個(gè)訂閱發(fā)布的例子。我們定義Android發(fā)布新的版本吠撮。Android為被觀察者尊惰,當(dāng)新版本發(fā)布的時(shí)候,我們通知所有觀察者泥兰,新版本已發(fā)布弄屡。
1、定義觀察者

public class PersonObserver implements Observer {
    static final String TAG = PersonObserver.class.getSimpleName();
    String name;

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

    @Override
    public void update(Observable observable, Object o) {
        Log.d(TAG,name + " 接收到通知啦 "+ o);
    }
}

觀察者就實(shí)現(xiàn)一個(gè)接口update方法鞋诗,當(dāng)被觀察者發(fā)送消息的時(shí)候膀捷,我們就在update里接收
2、定義被觀察者

public class AndroidObervable extends Observable {
    static final String TAG = AndroidObervable.class.getSimpleName();

    public void postNewVersion(String version) {
        setChanged(); // 標(biāo)示內(nèi)容發(fā)生改變
        notifyObservers(version);// 通知所有觀察者
    }
}

被觀察者繼承自O(shè)bservable师脂,Observable里已經(jīng)定義好了list,add,delete等方法担孔,很好理解。
3吃警、最后我們來(lái)看下怎么用的

        PersonObserver xiaoMing = new PersonObserver("xiaoMing");
        PersonObserver xiaoDong = new PersonObserver("xiaoDong");
        PersonObserver xiaoHong = new PersonObserver("xiaoHong");

       // 添加到集合里糕篇。
        AndroidObervable android = new AndroidObervable();
        android.addObserver(xiaoMing);
        android.addObserver(xiaoDong);
        android.addObserver(xiaoHong);
        // 通知
        android.postNewVersion("android O updated!");
        android.postNewVersion("android P updated!");
11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoMing 接收到通知啦 android O updated!
11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoDong 接收到通知啦 android O updated!
11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoHong 接收到通知啦 android O updated!
11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoMing 接收到通知啦 android P updated!
11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoDong 接收到通知啦 android P updated!
11-20 10:05:57.004 13623-13623/com.yink.designpattern.designpattern D/PersonObserver: xiaoHong 接收到通知啦 android P updated!

看輸出都通知到了。觀察者模式采用JDK原生的方式實(shí)現(xiàn)起來(lái)很簡(jiǎn)單酌心。JDK都給我們封裝好了拌消。只管添加就好。這個(gè)例子適合我們先對(duì)觀察者模式有一個(gè)大概理解,知道這就是觀察者模式墩崩。

例二

接下來(lái)我們自己來(lái)實(shí)現(xiàn)觀察者模式氓英。我們以觀察天氣變化為例。
1鹦筹、定義觀察者

public abstract class WeatherOberver {

    public void typhoon() {

    }

    public abstract void sun();

    public abstract void rain();
}

這里和例一的差別是铝阐,我們用的抽象類(lèi),沒(méi)用接口铐拐,他們思想都相似徘键。這里我是為了區(qū)分事件吹害,我們也可以用接口寫(xiě),然后把各種天氣用一個(gè)變量表示,這里就不詳述了。
2、定義被觀察者

public class WeatherObervable extends WeatherOberver{
    ArrayList<WeatherOberver> list = new ArrayList<>();

    public void add(WeatherOberver observerListener) {
        list.add(observerListener);
    }

    public void remove(WeatherOberver observerListener) {
        if (list.contains(observerListener)){
            list.remove(observerListener);
        }
    }

    @Override
    public void typhoon() {
        for (WeatherOberver observerListener : list) {
            observerListener.typhoon();
        }
    }

    @Override
    public void sun() {
        for (WeatherOberver observerListener : list) {
            observerListener.sun();
        }
    }

    @Override
    public void rain() {
        for (WeatherOberver observerListener : list) {
            observerListener.rain();
        }
    }
}

被觀察者的實(shí)現(xiàn)也是簡(jiǎn)單粗暴搂妻。這里就體現(xiàn)了我們文章開(kāi)始的時(shí)候說(shuō)的觀察者模式的核心了邓厕。一個(gè)list提供add,remove方法呵哨,把觀察者放到集合里敞掘。需要通知的時(shí)候遍歷通知即可。這下就好理解了吧。
3哭廉、最后看看調(diào)用。

private WeatherOberver xiaoDong = new WeatherOberver() {
        @Override
        public void typhoon() {
            Log.d("xiaoDong","吹臺(tái)風(fēng),要放假了加酵。哈哈!");
        }

        @Override
        public void sun() {

        }

        @Override
        public void rain() {
            Log.d("xiaoDong","下雨了哭当,帶傘");
        }
    };

    private WeatherOberver xiaoMing = new WeatherOberver() {

        @Override
        public void sun() {
            
        }

        @Override
        public void rain() {
            Log.d("xiaoMing","下雨了猪腕,帶傘");
        }
    };

WeatherObervable weatherObervable = new WeatherObervable();
weatherObervable.add(xiaoMing);
weatherObervable.add(xiaoDong);

weatherObervable.rain();
weatherObervable.typhoon();
11-20 11:16:21.284 15580-15580/com.yink.designpattern.designpattern D/xiaoMing: 下雨了,帶傘
11-20 11:16:21.284 15580-15580/com.yink.designpattern.designpattern D/xiaoDong: 下雨了钦勘,帶傘
11-20 11:16:21.284 15580-15580/com.yink.designpattern.designpattern D/xiaoDong: 吹臺(tái)風(fēng)陋葡,要放假了。哈哈彻采!

因?yàn)橛^察者我用的抽象類(lèi)腐缤,除了天晴和下雨是必須繼承的方法,刮臺(tái)風(fēng)可繼承可不繼承肛响。所以我們可以更方便的觀察我們需要觀察的對(duì)象岭粤。小東在廣東,吹臺(tái)風(fēng)他們公司就放假终惑。所以他只關(guān)心哪天吹臺(tái)風(fēng)绍在。小明比較講究健康,關(guān)注下雨,下雨就帶傘偿渡。

觀察者模式小結(jié)

觀察者模式就是將觀察者和被觀察者徹底隔離臼寄,實(shí)現(xiàn)解耦,只依賴(lài)于我們定義的抽象溜宽。觀察者模式運(yùn)用十分廣泛吉拳,比如我們的ListView運(yùn)用了觀察者模式和Adapter是的Listview的可擴(kuò)展性,靈活性非常強(qiáng)适揉。還有比較出名的開(kāi)源庫(kù)EventBus也是用了觀察者模式的思想實(shí)現(xiàn)解耦留攒。

總結(jié)

優(yōu)點(diǎn):1、觀察者和被觀察者解耦 2嫉嘀、增強(qiáng)靈活性炼邀,解耦
缺點(diǎn):由于java代碼的順序執(zhí)行,要考慮被察者的執(zhí)行效率剪侮,多個(gè)觀察者需要及時(shí)響應(yīng)就得考慮異步的問(wèn)題了拭宁。
觀察模式核心:一個(gè)list合集,提供add,remove方法瓣俯,遍歷觀察者杰标,就是一個(gè)list的遍歷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末彩匕,一起剝皮案震驚了整個(gè)濱河市腔剂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌驼仪,老刑警劉巖掸犬,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異谅畅,居然都是意外死亡登渣,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)毡泻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)胜茧,“玉大人,你說(shuō)我怎么就攤上這事仇味∩胪纾” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵丹墨,是天一觀的道長(zhǎng)廊遍。 經(jīng)常有香客問(wèn)我,道長(zhǎng)贩挣,這世上最難降的妖魔是什么喉前? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任没酣,我火速辦了婚禮,結(jié)果婚禮上卵迂,老公的妹妹穿的比我還像新娘裕便。我一直安慰自己,他們只是感情好见咒,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布偿衰。 她就那樣靜靜地躺著,像睡著了一般改览。 火紅的嫁衣襯著肌膚如雪下翎。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天宝当,我揣著相機(jī)與錄音视事,去河邊找鬼。 笑死庆揩,一個(gè)胖子當(dāng)著我的面吹牛郑口,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盾鳞,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼瞻离!你這毒婦竟也來(lái)了腾仅?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤套利,失蹤者是張志新(化名)和其女友劉穎推励,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體肉迫,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡验辞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了喊衫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跌造。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖族购,靈堂內(nèi)的尸體忽然破棺而出壳贪,到底是詐尸還是另有隱情,我是刑警寧澤寝杖,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布违施,位于F島的核電站,受9級(jí)特大地震影響瑟幕,放射性物質(zhì)發(fā)生泄漏磕蒲。R本人自食惡果不足惜留潦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辣往。 院中可真熱鬧兔院,春花似錦、人聲如沸排吴。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)钻哩。三九已至屹堰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間街氢,已是汗流浹背扯键。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留珊肃,地道東北人荣刑。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像伦乔,于是被迫代替她去往敵國(guó)和親厉亏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,756評(píng)論 25 707
  • 用兩張圖告訴你烈和,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料爱只? 從這篇文章中你...
    hw1212閱讀 12,699評(píng)論 2 59
  • 概念: 定義了對(duì)象之間的一對(duì)多依賴(lài),這樣一來(lái)招刹,當(dāng)一個(gè)對(duì)象改變狀態(tài)時(shí)恬试,它的所有依賴(lài)者都會(huì)收到通知并自動(dòng)更新。 四個(gè)元...
    藍(lán)庫(kù)知識(shí)閱讀 519評(píng)論 0 0
  • 打飛的回北京疯暑,參加最后一個(gè)脫單鐵桿閨蜜的婚禮训柴,也是好癡情啊,我的鷹終于還是嫁人了妇拯。 其實(shí)我不是第一次寫(xiě)鷹的故事了幻馁,...
    黃婷婷Aimee閱讀 273評(píng)論 0 0
  • 仲蕊蕊媽媽閱讀 146評(píng)論 0 1