設計模式-觀察者模式(十七)

觀察者(Observer)模式,又叫 發(fā)布-訂閱(Publish/Subscribe)模式镣陕,模型-視圖(Model-View)模式
定義了一種一對多的依賴關(guān)系谴餐,當主題對象發(fā)生改變的時候會通知所有的觀察者對象。

一個變化其他的相應變化
設計目標:低耦合 + 行動的協(xié)調(diào)一致

上類圖:


觀察者模式.png

java類庫對該模式的支持:
java JDK中定義了Observer接口呆抑,以及 Observable的主題角色


AWT1.1+岂嗓,Servlet的委派事件模型(DEM Delegation Event Model)


優(yōu)缺點:
優(yōu)點:觀察者和被觀察者建立了一個抽象的耦合
缺點:

  1. 如果觀察者比較多,全部通知一下比較耗時
  2. 如果被觀察者之間有循環(huán)依賴會導致系統(tǒng)崩潰

  • 代碼示例:
  1. 定義個抽象觀察者對象鹊碍,可以直接用JDK自帶的Observer接口
package com.byedbl.observer;

/**
 *  Observer interface
 */
public interface Observer {
    public void update(Subject s);
}
  1. 實現(xiàn)兩個觀察者
package com.byedbl.observer;
/**
 *  A concrete observer
 *  This concrete observer can change subject through call
 *  a concrete subject setState function
 */
import java.util.Vector;

public class ObserverA implements Observer {
    private Vector strVector;
    private Subject sub;
    public ObserverA(Subject s) {
        sub = s;
        //strVector = new Vector();
    }
    public void update(Subject subject) {
        strVector = subject.getState();
        System.out.println("----- ObserverA will be updated -----");
        for(int i = 0; i < strVector.size(); i++) {
            System.out.println("Num " + i + " is :" + (String)strVector.get(i));
        }
    }
    public void change(String action, String str) {
        sub.setState(action, str);
        //we can auto update
        //sub.sendNotify();
    }
    public void notifySub() {
        sub.sendNotify();
    }
}
package com.byedbl.observer; /**
 *  A concrete observer
 *  This observer, can not change subject, 
 *  but it can print the content in vector sorted by alphameric
 */
import java.util.Vector;

public class ObserverB implements Observer {
    private Vector strVector;
    public ObserverB() {
        strVector =  new Vector();
    }
    public void update(Subject subject) {
        strVector = (Vector)(subject.getState()).clone();
        //-----  Sorted vector  ---------------------------
        for (int i = strVector.size(); --i >= 0; ) {
            for (int j = 0; j < i; j++) {
                String str1 = (String)strVector.get(j);
                String str2 = (String)strVector.get(j+1);
                if((str1.compareTo(str2)) > 0) {
                    strVector.setElementAt(str2, j);
                    strVector.setElementAt(str1, j+1);
                }
            }
        }
        System.out.println("----- ObserverB will be updated -----");
        for(int i = 0; i < strVector.size(); i++) {
            System.out.println("Num " + i + " is :" + (String)strVector.get(i));
        }
    }
    
}
  1. 定義抽象主題角色
package com.byedbl.observer; /**
 *  Subject interface
 *  In this interface , we can only declare top 3 function, 
 *  other function we can define in an abstract class which implements
 *  this interface
 */
import java.util.*;

public interface Subject  {
    public abstract void attach(Observer o);
    public abstract void detach(Observer o);
    public abstract void sendNotify();

    public abstract Vector getState();
    public abstract void setState(String act, String str);
}
  1. 實現(xiàn)抽象主題角色
package com.byedbl.observer;
/**
 * A concrete subject
 */

import java.util.LinkedList;
import java.util.Vector;

public class ConcreteSubject implements Subject {
    private LinkedList observerList;
    private Vector strVector;

    public ConcreteSubject() {
        observerList = new LinkedList();
        strVector = new Vector();
    }

    public void attach(Observer o) {
        observerList.add(o);
    }

    public void detach(Observer o) {
        observerList.remove(o);
    }

    public void sendNotify() {
        for (int i = 0; i < observerList.size(); i++) {
            ((Observer) observerList.get(i)).update(this);
        }
    }

    public void setState(String act, String str) {
        if (act.equals("ADD")) {
            strVector.add(str);
        } else if (act.equals("DEL")) {
            strVector.remove(str);
        }
    }

    public Vector getState() {
        return strVector;
    }
}
  1. 客戶端代碼
package com.byedbl.observer;
/**
 * A concrete subject
 */

import java.util.LinkedList;
import java.util.Vector;

public class ConcreteSubject implements Subject {
    private LinkedList observerList;
    private Vector strVector;

    public ConcreteSubject() {
        observerList = new LinkedList();
        strVector = new Vector();
    }

    public void attach(Observer o) {
        observerList.add(o);
    }

    public void detach(Observer o) {
        observerList.remove(o);
    }

    public void sendNotify() {
        for (int i = 0; i < observerList.size(); i++) {
            ((Observer) observerList.get(i)).update(this);
        }
    }

    public void setState(String act, String str) {
        if (act.equals("ADD")) {
            strVector.add(str);
        } else if (act.equals("DEL")) {
            strVector.remove(str);
        }
    }

    public Vector getState() {
        return strVector;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末厌殉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子侈咕,更是在濱河造成了極大的恐慌公罕,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耀销,死亡現(xiàn)場離奇詭異楼眷,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門摩桶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桥状,“玉大人帽揪,你說我怎么就攤上這事硝清。” “怎么了转晰?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵芦拿,是天一觀的道長。 經(jīng)常有香客問我查邢,道長蔗崎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任扰藕,我火速辦了婚禮缓苛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘邓深。我一直安慰自己未桥,他們只是感情好,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布芥备。 她就那樣靜靜地躺著冬耿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪萌壳。 梳的紋絲不亂的頭發(fā)上亦镶,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機與錄音袱瓮,去河邊找鬼缤骨。 笑死,一個胖子當著我的面吹牛尺借,可吹牛的內(nèi)容都是我干的荷憋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼褐望,長吁一口氣:“原來是場噩夢啊……” “哼勒庄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瘫里,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤实蔽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谨读,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體局装,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了铐尚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拨脉。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖宣增,靈堂內(nèi)的尸體忽然破棺而出玫膀,到底是詐尸還是另有隱情,我是刑警寧澤爹脾,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布帖旨,位于F島的核電站,受9級特大地震影響灵妨,放射性物質(zhì)發(fā)生泄漏解阅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一泌霍、第九天 我趴在偏房一處隱蔽的房頂上張望货抄。 院中可真熱鬧,春花似錦朱转、人聲如沸蟹地。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锈津。三九已至,卻和暖如春凉蜂,著一層夾襖步出監(jiān)牢的瞬間琼梆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工窿吩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留茎杂,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓纫雁,卻偏偏與公主長得像煌往,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子轧邪,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

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

  • 設計模式匯總 一刽脖、基礎(chǔ)知識 1. 設計模式概述 定義:設計模式(Design Pattern)是一套被反復使用、多...
    MinoyJet閱讀 3,948評論 1 15
  • 【學習難度:★★★☆☆忌愚,使用頻率:★★★★★】直接出處:觀察者模式梳理和學習:https://github.com...
    BruceOuyang閱讀 1,529評論 1 5
  • 本文的結(jié)構(gòu)如下: 什么是觀察者模式 為什么要用該模式 模式的結(jié)構(gòu) 代碼示例 推模型和拉模型 優(yōu)點和缺點 適用環(huán)境 ...
    w1992wishes閱讀 1,439評論 0 16
  • 中國茶葉的分類曲管,大致根據(jù)發(fā)酵程度或者制作工藝而分成了六大主類,相對于綠茶紅茶等常見的茶類硕糊,我們還有一個既熟悉又陌生...
    茶人未曉師古坊主人閱讀 432評論 1 2
  • 高中時已讀過幾遍《紅樓夢》院水,然而心中一直帶著遺憾腊徙。不得不把心思放在考點上,沒有機會自由感悟它的韻味檬某。所以撬腾,我又打開...
    繁縷_2991閱讀 254評論 0 1