設(shè)計(jì)模式-觀察者模式(十七)

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

一個(gè)變化其他的相應(yīng)變化
設(shè)計(jì)目標(biāo):低耦合 + 行動(dòng)的協(xié)調(diào)一致

上類圖:


觀察者模式.png

java類庫(kù)對(duì)該模式的支持:
java JDK中定義了Observer接口,以及 Observable的主題角色


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


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

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

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

/**
 *  Observer interface
 */
public interface Observer {
    public void update(Subject s);
}
  1. 實(shí)現(xiàn)兩個(gè)觀察者
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. 實(shí)現(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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容