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

觀察者模式(Observer),又叫發(fā)布-訂閱模式(Publish/Subscribe)开泽,定義了一種一對(duì)多的依賴關(guān)系牡拇,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象。這個(gè)主體對(duì)象在狀態(tài)發(fā)生變化時(shí)穆律,會(huì)通知所有觀察者對(duì)象惠呼,使它們能夠自動(dòng)更新自己。

適用場(chǎng)景

當(dāng)一個(gè)對(duì)象的改變需要同時(shí)改變其他對(duì)象的時(shí)候峦耘,而且它不知道具體有多少對(duì)象有待改變時(shí)罢杉,應(yīng)該考慮使用觀察者模式。一個(gè)抽象模型有兩個(gè)方面贡歧,其中一方面依賴于另一方面滩租,這時(shí)用觀察者模式可以將這兩者封裝在獨(dú)立的對(duì)象中使它們各自的獨(dú)立的改變和復(fù)用赋秀。

優(yōu)點(diǎn)

  1. 觀察者模式在被觀察者和觀察者之間建立一個(gè)抽象的耦合。
  2. 觀察者模式支持廣播通訊律想。

缺點(diǎn)

  1. 如果一個(gè)被觀察者對(duì)象有很多的直接和間接的觀察者的話猎莲,將所有的觀察者都通知到會(huì)花費(fèi)很多時(shí)間。
  2. 如果在被觀察者之間有循環(huán)依賴的話技即,被觀察者會(huì)觸發(fā)它們之間進(jìn)行循環(huán)調(diào)用著洼,導(dǎo)致系統(tǒng)崩潰。在使用觀察者模式是要特別注意這一點(diǎn)而叼。
  3. 如果對(duì)觀察者的通知是通過(guò)另外的線程進(jìn)行異步投遞的話身笤,系統(tǒng)必須保證投遞是以自恰的方式進(jìn)行的。
  4. 雖然觀察者模式可以隨時(shí)使觀察者知道所觀察的對(duì)象發(fā)生了變化葵陵,但是觀察者模式?jīng)]有相應(yīng)的機(jī)制使觀察者知道所觀察的對(duì)象是怎么發(fā)生變化的液荸。

UML結(jié)構(gòu)圖

ObserverPattern

源碼

Subject:主題或叫抽象通知者

/**
 * 主題或叫抽象通知者
 *
 * Created by zhenguo on 11/29/14.
 */
public abstract class Subject {

    private List<Observer> observers = new ArrayList<Observer>();

    /**
     * 增加觀察者
     * @param observer
     */
    public void attach(Observer observer) {
        observers.add(observer);
    }

    /**
     * 移除觀察者
     * @param observer
     */
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    /**
     * 通知所有觀察者
     */
    public void notifyAllObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }

}

Observer:抽象觀察者

/**
 * 抽象觀察者
 *
 * Created by zhenguo on 11/29/14.
 */
public abstract class Observer {

    public abstract void update();

}

ConcreteSubject:具體主題或具體通知者

/**
 * 具體主題或具體通知者
 *
 * Created by zhenguo on 11/29/14.
 */
public class ConcreteSubject extends Subject {

    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

ConcreteObserver:具體觀察者

/**
 * 具體觀察者
 *
 * Created by zhenguo on 11/29/14.
 */
public class ConcreteObserver extends Observer {

    private String name;
    private ConcreteSubject subject;

    public ConcreteObserver(String name, ConcreteSubject subject) {
        this.name = name;
        this.subject = subject;
    }

    @Override
    public void update() {
        System.out.println("觀察者 " + name + " 的狀態(tài)是 " + subject.getState());
    }

    public ConcreteSubject getSubject() {
        return subject;
    }

    public void setSubject(ConcreteSubject subject) {
        this.subject = subject;
    }
}

Client:客戶端調(diào)用

/**
 * 客戶端調(diào)用
 * 觀察者模式(Observer),又叫發(fā)布-訂閱模式(Publish/Subscribe)脱篙,定義了一種一對(duì)多的依賴關(guān)系娇钱,讓多個(gè)觀察者對(duì)象
 * 同時(shí)監(jiān)聽某一個(gè)主題對(duì)象。這個(gè)主體對(duì)象在狀態(tài)發(fā)生變化時(shí)绊困,會(huì)通知所有觀察者對(duì)象文搂,使它們能夠自動(dòng)更新自己。
 *
 * Created by zhenguo on 11/29/14.
 */
public class Client {

    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();

        subject.attach(new ConcreteObserver("A", subject));
        subject.attach(new ConcreteObserver("B", subject));
        subject.attach(new ConcreteObserver("C", subject));

        subject.setState("XYZ");
        subject.notifyAllObservers();

    }

}

設(shè)計(jì)模式系列:

創(chuàng)建型 結(jié)構(gòu)型 行為型
工廠方法
簡(jiǎn)單工廠
抽象工廠
建造者模式
單例模式
原型模式
組合模式
外觀模式
橋接模式
代理模式
享元模式
適配器模式
裝飾模式
策略模式
模板方法
狀態(tài)模式
觀察者模式
備忘錄模式
迭代器模式
命令模式
職責(zé)鏈模式
解釋器模式
訪問者模式
中介者模式
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秤朗,一起剝皮案震驚了整個(gè)濱河市煤蹭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌取视,老刑警劉巖硝皂,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異贫途,居然都是意外死亡吧彪,警方通過(guò)查閱死者的電腦和手機(jī)待侵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門丢早,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人秧倾,你說(shuō)我怎么就攤上這事怨酝。” “怎么了那先?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵农猬,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我售淡,道長(zhǎng)斤葱,這世上最難降的妖魔是什么慷垮? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮揍堕,結(jié)果婚禮上料身,老公的妹妹穿的比我還像新娘。我一直安慰自己衩茸,他們只是感情好芹血,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著楞慈,像睡著了一般幔烛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上囊蓝,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天饿悬,我揣著相機(jī)與錄音,去河邊找鬼慎颗。 笑死乡恕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的俯萎。 我是一名探鬼主播傲宜,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼夫啊!你這毒婦竟也來(lái)了函卒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤撇眯,失蹤者是張志新(化名)和其女友劉穎报嵌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體熊榛,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锚国,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玄坦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片血筑。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖煎楣,靈堂內(nèi)的尸體忽然破棺而出豺总,到底是詐尸還是另有隱情,我是刑警寧澤择懂,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布喻喳,位于F島的核電站,受9級(jí)特大地震影響困曙,放射性物質(zhì)發(fā)生泄漏表伦。R本人自食惡果不足惜谦去,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹦哼。 院中可真熱鬧哪轿,春花似錦、人聲如沸翔怎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赤套。三九已至飘痛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間容握,已是汗流浹背宣脉。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留剔氏,地道東北人塑猖。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像谈跛,于是被迫代替她去往敵國(guó)和親羊苟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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

  • 前言 Observer本來(lái)的意思是“觀察者”感憾,但是實(shí)際上Observer角色并非主動(dòng)的去觀察蜡励,而是被動(dòng)的接收來(lái)自觀...
    Code4Android閱讀 462評(píng)論 0 2
  • 使用場(chǎng)景 一個(gè)抽象模型有兩個(gè)方面,其中一個(gè)方面依賴于另一個(gè)方面阻桅。將這些方面封裝在獨(dú)立的對(duì)象中使它們可以各自獨(dú)立地改...
    niaoge2016閱讀 749評(píng)論 0 1
  • 客戶需求 程序設(shè)計(jì) 一個(gè)氣象站對(duì)應(yīng)著多個(gè)客戶端凉倚,氣象站的數(shù)據(jù)一發(fā)生變化,客戶端的數(shù)據(jù)也要隨著更新嫂沉,這就形成了一種依...
    BlainPeng閱讀 992評(píng)論 1 17
  • 前言定義:觀察者設(shè)計(jì)模式定義了對(duì)象間的一種一對(duì)多的依賴關(guān)系稽寒,以便一個(gè)對(duì)象的狀態(tài)發(fā)生變化時(shí),所有依賴于它的對(duì)象都得到...
    xsp單細(xì)胞閱讀 449評(píng)論 0 1
  • 一直想念一個(gè)人趟章,在很多次沙盤培訓(xùn)課程上對(duì)學(xué)生提起過(guò)他杏糙。那是來(lái)自云南的一位同行,在一次沙盤小組的練習(xí)中尤揣,陪...
    暉哥兒閱讀 688評(píng)論 2 7