觀察者設(shè)計模式

觀察者設(shè)計模式是使用最頻繁的設(shè)計模式之一,在很多的地方都用使用到展东,比如:RxJava,EventBus,以及GUI的各種事件中等等棒拂。
一倒谷、初步認(rèn)識:
過年放假回家都需要提前買票莱坎,但是對于土豪就不需要買票了哈衣式,往往都是通過小程序,App等一些渠道去購買檐什,都怕錯過搶票的時間碴卧,于是我們關(guān)注了12306購票小程序,進(jìn)行購買火車票乃正,買完之后就取消關(guān)注小程序住册。
上面存在幾個角色小程序(被觀察者 ),需要購買后車票的人(觀察者)是用過關(guān)注將兩者進(jìn)行聯(lián)系起來,當(dāng)關(guān)注之后被觀察者有狀態(tài)改變瓮具,都會立即通知被觀察者荧飞,觀察者根據(jù)自己的情況做出相應(yīng)的動作。
二搭综、進(jìn)步熟悉:
上面我們大概對觀察者的作用有了淺層的認(rèn)識,這對接下來的學(xué)習(xí)很有幫助划栓。
1.首先來看一下觀察者模式(Observe Pattern)的正經(jīng)定義:定義對象之間的一對多依賴關(guān)系兑巾,使得每當(dāng)一個對象狀態(tài)發(fā)生改變時,其相關(guān)依賴對象皆得到通知并被自動更新忠荞。
2.那么它如何實現(xiàn)這么神奇的功能的呢蒋歌?
先來看一下它的結(jié)構(gòu)圖
image.png
從圖中我們可以看到之前說的目標(biāo)和觀察者。只不過這里的目標(biāo)和觀察者都被抽象化了委煤。我們來逐一認(rèn)識:
(1)Observable(被觀察者)
它是指被觀察者的對象中堂油,提供一系列對觀察者進(jìn)行管理的方法,比如addObserver()添加到集合中碧绞,removeObserver()從集合中移出去府框,nofityObservers()通知集合中所有的觀察者,pushObservers()給集合中所有的觀察者推送消息讥邻。
(2)WeChatServerObservable(具體目標(biāo))
當(dāng)它的狀態(tài)的改變時就會通知各個觀察者迫靖,同時還實現(xiàn)了在目標(biāo)類中定義的抽象邏輯方法(如果有的話)
(3)Observer(抽象觀察者)
它是一個接口院峡,觀察者將對觀察目標(biāo)狀態(tài)的改變做出相應(yīng)的反應(yīng)該接口定義了更新數(shù)據(jù)的方法update。
(4)UserPerson(抽象觀察者)
它實現(xiàn)了抽象觀察者對象的updata方法系宜。
3.接下來通過一個代碼實例來加深對上面的結(jié)構(gòu)圖的理解
目標(biāo)Observable.java
interface Observable {
    //添加觀察者
    fun addObserver(observer:Observer)
    //移除觀察者
    fun removeObserver(observer: Observer)
    //推送消息給觀察者
    fun pushObservers(message:Any)
    //通知所有的觀察者
    fun nofityObservers()
}
具體目標(biāo)類WeChatServerObservable.java
class WeChatServerObservable :Observable {

    private var observers:MutableList<Observer> = ArrayList()
    private var message:Any?=null;

    override fun addObserver(observer: Observer) {
        observers.add(observer!!)
    }

    override fun removeObserver(observer: Observer) {
        observers.remove(observer)
    }

    override fun nofityObservers() {
        observers.forEach {
            it.update(message!!)
        }
    }

    override fun pushObservers(message: Any) {
        this.message= message
        nofityObservers()
    }
}
觀察者接口 Observer 定義一個更新的方法
interface Observer {
    fun update(mssage:Any)
}
具體的觀察者 UserPerson.java
class UserPerson :Observer{
    private var name:String?=null
    constructor(name:String){
        this.name =name
    }
    override fun update(mssage: Any) {
        Log.e("TAG","$name----$mssage")
    }
}
最后測試:
public static void main(String[] args) {
        test();
    }
    public static void test(){
        //創(chuàng)建一個微信服務(wù)
        Observable observable =new WeChatServerObservable();
        //創(chuàng)建多個觀察者
        Observer user1 =new UserPerson("小胖1");
        Observer user2 =new UserPerson("小胖2");
        observable.addObserver(user1);
        observable.addObserver(user2);
        //推送消息
        observable.pushObservers("明天早上八點開始搶票照激!");
    }

#######將兩個觀察者添通過addObserver()方法添加到觀察者集合中,然后由目標(biāo)來發(fā)送一條更新的消息盹牧。觀察者接收到消息后做出反應(yīng)俩垃。運行結(jié)果如下:

image.png
三、總結(jié)告別
優(yōu)點:
1汰寓、觀察者模式可以實現(xiàn)表示層和數(shù)據(jù)邏輯層的分離口柳,定義了穩(wěn)定的消息傳遞機制,并抽象了更新接口踩寇,使得可以有各種各樣的表示層充當(dāng)具體的觀察者角色啄清。
2、觀察者模式在觀察目標(biāo)和觀察者之間建立一個抽象的耦合俺孙。觀察者對象只需要維持一個抽象觀察者的集合辣卒,無需了解其具體觀察者。
3睛榄、觀察者模式支持廣播通信荣茫,觀察目標(biāo)會向所有已注冊的觀察者發(fā)送通知,降低了一對多系統(tǒng)的設(shè)計難度场靴。
缺點:
1啡莉、如果是一對多的關(guān)系(被觀察者與觀察者)所有觀察者收到消息,則需要花費大量的時間旨剥。
2咧欣、雖然觀察者模式可以隨時使觀察者知道所觀察的對象發(fā)生了變化,但是觀察者模式?jīng)]有相應(yīng)的機制使觀察者知道所觀察的對象是怎么發(fā)生變化的轨帜。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末魄咕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蚌父,更是在濱河造成了極大的恐慌哮兰,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苟弛,死亡現(xiàn)場離奇詭異喝滞,居然都是意外死亡,警方通過查閱死者的電腦和手機膏秫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門右遭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事狸演⊙陨撸” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵宵距,是天一觀的道長腊尚。 經(jīng)常有香客問我,道長满哪,這世上最難降的妖魔是什么婿斥? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮哨鸭,結(jié)果婚禮上民宿,老公的妹妹穿的比我還像新娘。我一直安慰自己像鸡,他們只是感情好活鹰,可當(dāng)我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著只估,像睡著了一般志群。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蛔钙,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天锌云,我揣著相機與錄音,去河邊找鬼吁脱。 笑死桑涎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的兼贡。 我是一名探鬼主播攻冷,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼遍希!你這毒婦竟也來了等曼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤孵班,失蹤者是張志新(化名)和其女友劉穎涉兽,沒想到半個月后招驴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體篙程,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年别厘,在試婚紗的時候發(fā)現(xiàn)自己被綠了虱饿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖氮发,靈堂內(nèi)的尸體忽然破棺而出渴肉,到底是詐尸還是另有隱情,我是刑警寧澤爽冕,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布仇祭,位于F島的核電站,受9級特大地震影響颈畸,放射性物質(zhì)發(fā)生泄漏乌奇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一眯娱、第九天 我趴在偏房一處隱蔽的房頂上張望礁苗。 院中可真熱鬧,春花似錦徙缴、人聲如沸试伙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疏叨。三九已至,卻和暖如春百宇,著一層夾襖步出監(jiān)牢的瞬間考廉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工携御, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留昌粤,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓啄刹,卻偏偏與公主長得像涮坐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子誓军,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,494評論 2 348