觀察者模式

定義

觀察者模式定義了對(duì)象間一對(duì)多的依賴(lài)關(guān)系,使得對(duì)象狀態(tài)發(fā)生變化時(shí)秕磷,所有依賴(lài)它的對(duì)象都會(huì)受到通知并且自動(dòng)更新自己。通俗來(lái)說(shuō)就是多個(gè)觀察者訂閱了一個(gè)被觀察者的時(shí)候,被觀察者發(fā)生改變時(shí)引镊,會(huì)自動(dòng)通知觀察者,而不需要觀察者去詢(xún)問(wèn)被觀察者是否發(fā)生改變。

觀察者模式中的角色組成

  • 抽象被觀察者角色:定義了添加弟头,刪除和通知觀察者的方法吩抓。
  • 具體被觀察者角色:繼承抽象被觀察者的抽象類(lèi),實(shí)現(xiàn)自身的業(yè)務(wù)邏輯赴恨,當(dāng)狀態(tài)發(fā)生改變時(shí)疹娶,發(fā)起通知。
  • 抽象觀察者角色:提供一個(gè)接口伦连,定義了觀察者收到通知時(shí)更新自己的方法雨饺。
  • 具有觀察者角色:實(shí)現(xiàn)抽象觀察者接口,處理不同具體觀察者的不同業(yè)務(wù)邏輯惑淳。

實(shí)例

現(xiàn)在有一個(gè)讀書(shū)平臺(tái)额港,有很多個(gè)讀者訂閱了一個(gè)作者的說(shuō),但是這個(gè)作者更新時(shí)間是不一定的歧焦,讀者們都想第一去讀到最新的章節(jié)移斩,但是讀者又不能時(shí)刻去關(guān)注作者是否已經(jīng)更新,因此很多讀者要求作者在更新小說(shuō)的時(shí)候绢馍。并且當(dāng)讀者不想訂閱的時(shí)候向瓷,可以取消訂閱。這個(gè)時(shí)候我們就可以使用觀察者模式解決這個(gè)問(wèn)題舰涌。

被觀察者的抽象類(lèi):

這個(gè)類(lèi)是抽象類(lèi)猖任,是所有被觀察者都要求繼承的,其中提供了添加瓷耙,刪觀察者超升,支持只通知個(gè)別的觀察者,或者所有的觀察者的功能哺徊。


/**
 * 被觀察者的抽象類(lèi)
 *
 */
abstract class Subject{
    private List<Observer> observers=new ArrayList<Observer>();
    
    
    /**
     * 訂閱的方法
     * @param observer
     */
    public void subscribe(Observer observer) {
        if (observer!=null) {
            if (!observers.contains(observer)) {
                observers.add(observer);
                System.out.println(observer.getObserverName()+"訂閱了");
            }
            
        }
    }
    /**
     * 取消訂閱
     */
    public void unSubscribe(Observer observer) {
        if (observers.contains(observer)) {
            observers.remove(observer);
            System.out.println(observer.getObserverName()+"取消訂閱了");
        }
    }
    /**
     * 通知一個(gè)觀察者
     * @param observer
     */
    public void notifyObserver(Observer observer) {
        if (observer!=null) {
            observer.update(" 已經(jīng)更新: "+notifyUpadteContext());
        }
    }
    /**
     * 通知所有的觀察者
     *
     */
    public void notifyAllObserver() {
        for(Observer observer:observers) {
            notifyObserver(observer);
        }
    }
    /**
     * 子類(lèi)要實(shí)現(xiàn)的更新小說(shuō)的方法室琢,返回更新的內(nèi)容
     * @return
     */
    public abstract String  notifyUpadteContext();
}

被觀察者的實(shí)現(xiàn)類(lèi)

被觀察者的實(shí)現(xiàn)類(lèi),在這個(gè)案例當(dāng)中落追,小說(shuō)作者就是被觀察者盈滴,發(fā)布更新的消息,并通知觀察者轿钠。

/**
 * 小說(shuō)作者巢钓,即是被觀察者
 *
 */
class WriterSubject extends Subject{
    private String mUpdateContext;
    
    public void write(String context) {
        mUpdateContext=context;
        //通知更新所有的觀察者
       notifyAllObserver();
    }
    public void write(String context,Observer observer) {
        mUpdateContext=context;
        //通知更新個(gè)別的觀察者
         notifyObserver(observer);
    }
    
    /**
     * 返回更新的內(nèi)容,只有父類(lèi)去調(diào)用獲得的內(nèi)容通知觀察者
     */
    @Override
    public String notifyUpadteContext() {
        return mUpdateContext;
    }
}

觀察者的接口

觀察者的接口疗垛,最重要的方法是收到被觀察者的更新消息之后去做相關(guān)的邏輯處理症汹。

/**
 * 觀察者的接口
 *
 */
interface  Observer{
    /**
     * 返回觀察者的名稱(chēng)
     * @return
     */
    String getObserverName();
    
    /**
     * 進(jìn)行更新的操作
     * @param message
     */
    void update(String message);
}

具體的觀察者

具體的觀察者,等到更新的做出具體的處理贷腕。

class XiaoMing implements Observer{
    @Override
    public String getObserverName() {
        
        return "小明";
    }

    @Override
    public void update(String message) {
        System.out.println("小明收到小說(shuō)更新的通知:"+message);
    }
    
}
class XiaoHong implements Observer{
    @Override
    public String getObserverName() {
        
        return "小紅";
    }

    @Override
    public void update(String message) {
        System.out.println("小紅收到小說(shuō)更新的通知:"+message);
    }
    
}
class XiaoBai implements Observer{
    @Override
    public String getObserverName() {
        
        return "小白";
    }

    @Override
    public void update(String message) {
        System.out.println("小白收到小說(shuō)更新的通知:"+message);
    }
    
}

調(diào)用代碼:

public static void main(String[] args) {
        WriterSubject  writerSubject=new WriterSubject();
        XiaoMing xiaoMing=new XiaoMing();
        XiaoHong xiaoHong=new XiaoHong();
        XiaoBai xiaoBai=new XiaoBai();
        writerSubject.subscribe(xiaoMing);
        writerSubject.subscribe(xiaoBai);
        writerSubject.subscribe(xiaoHong);
        writerSubject.write("第10章");
        writerSubject.write("第11章",xiaoMing);
        writerSubject.unSubscribe(xiaoBai);
        writerSubject.write("第12章");
    }

結(jié)果:


image.png

從結(jié)果可以看到當(dāng)被觀察者更新了小說(shuō)之后背镇,訂閱的觀察者們將會(huì)作出相應(yīng)的處理咬展,觀察者模式在我看來(lái)的核心就是Android開(kāi)發(fā)中用到的接口回調(diào)的思路。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瞒斩,一起剝皮案震驚了整個(gè)濱河市破婆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胸囱,老刑警劉巖祷舀,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異烹笔,居然都是意外死亡裳扯,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)谤职,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)饰豺,“玉大人,你說(shuō)我怎么就攤上這事柬帕∮慈蹋” “怎么了狡门?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵陷寝,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我其馏,道長(zhǎng)凤跑,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任叛复,我火速辦了婚禮仔引,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘褐奥。我一直安慰自己咖耘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布撬码。 她就那樣靜靜地躺著儿倒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪呜笑。 梳的紋絲不亂的頭發(fā)上夫否,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音叫胁,去河邊找鬼凰慈。 笑死,一個(gè)胖子當(dāng)著我的面吹牛驼鹅,可吹牛的內(nèi)容都是我干的微谓。 我是一名探鬼主播森篷,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼堰酿!你這毒婦竟也來(lái)了疾宏?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤触创,失蹤者是張志新(化名)和其女友劉穎坎藐,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體哼绑,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岩馍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抖韩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛀恩。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖茂浮,靈堂內(nèi)的尸體忽然破棺而出双谆,到底是詐尸還是另有隱情,我是刑警寧澤席揽,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布顽馋,位于F島的核電站,受9級(jí)特大地震影響幌羞,放射性物質(zhì)發(fā)生泄漏寸谜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一属桦、第九天 我趴在偏房一處隱蔽的房頂上張望熊痴。 院中可真熱鬧,春花似錦聂宾、人聲如沸果善。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)巾陕。三九已至,卻和暖如春蔚鸥,著一層夾襖步出監(jiān)牢的瞬間惜论,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工止喷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留馆类,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓弹谁,卻偏偏與公主長(zhǎng)得像乾巧,于是被迫代替她去往敵國(guó)和親句喜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344