觀察者模式

精髓:

觀察者模式其實(shí)就是發(fā)布訂閱模式,發(fā)布者發(fā)布信息,訂閱者獲取信息,訂閱了就能收到信息,沒(méi)訂閱就收不到信息。

角色:
  1. 抽象被觀察者角色:也就是一個(gè)抽象主題,它把所有對(duì)觀察者對(duì)象的引用保存在一個(gè)集合中,每個(gè)主題都可以有任意數(shù)量的觀察者。抽象主題提供一個(gè)接口,可以增加和刪除觀察者角色。一般用一個(gè)抽象類(lèi)和接口來(lái)實(shí)現(xiàn)。
  2. 抽象觀察者角色:為所有的具體觀察者定義一個(gè)接口,在得到主題通知時(shí)更新自己。
  3. 具體被觀察者角色:也就是一個(gè)具體的主題,在集體主題的內(nèi)部狀態(tài)改變時(shí),所有登記過(guò)的觀察者發(fā)出通知。
  4. 具體觀察者角色:實(shí)現(xiàn)抽象觀察者角色所需要的更新接口,一邊使本身的狀態(tài)與制圖的狀態(tài)相協(xié)調(diào)。
代碼示例:
  1. 示例場(chǎng)景
    有一個(gè)微信公眾號(hào)服務(wù),不定時(shí)發(fā)布一些消息,關(guān)注公眾號(hào)就可以收到推送消息,取消關(guān)注就收不到推送消息。
  2. 定義一個(gè)抽象被觀察者接口
/***
 * 抽象被觀察者接口
 * 聲明了添加、刪除、通知觀察者方法
 */
public interface Observerable {
    // 關(guān)注公眾號(hào)
    public void registerObserver(Observer o);
    // 取消關(guān)注公眾號(hào)
    public void removeObserver(Observer o);
    // 發(fā)布公眾號(hào)消息
    public void notifyObserver();
}
  1. 定義一個(gè)抽象觀察者接口
/***
 * 抽象觀察者
 * 接受公眾號(hào)消息方法
 */
public interface Observer {
    // 定義了一個(gè)update()方法,當(dāng)被觀察者調(diào)用notifyObservers()方法時(shí),觀察者的update()方法會(huì)被回調(diào)。
    public void update(String message);
}
  1. 定義被觀察者,實(shí)現(xiàn)了Observerable接口,對(duì)Observerable接口的三個(gè)方法進(jìn)行了具體實(shí)現(xiàn),同時(shí)有一個(gè)List集合,用以保存注冊(cè)的觀察者,等需要通知觀察者時(shí),遍歷該集合即可
/**
 * 被觀察者,也就是微信公眾號(hào)服務(wù)
 * 實(shí)現(xiàn)了Observerable接口,對(duì)Observerable接口的三個(gè)方法進(jìn)行了具體實(shí)現(xiàn)
 */
public class WechatServer implements Observerable {
    
    //注意到這個(gè)List集合的泛型參數(shù)為Observer接口,設(shè)計(jì)原則:面向接口編程而不是面向?qū)崿F(xiàn)編程
    private List<Observer> list;
    private String message;
    
    public WechatServer() {
        list = new ArrayList<Observer>();
    }
    
    @Override
    public void registerObserver(Observer o) {
        list.add(o);
    }
    
    @Override
    public void removeObserver(Observer o) {
        if(!list.isEmpty())
            list.remove(o);
    }

    //遍歷
    @Override
    public void notifyObserver() {
        for(int i = 0; i < list.size(); i++) {
            Observer oserver = list.get(i);
            oserver.update(message);
        }
    }
    
    public void setInfomation(String s) {
        this.message = s;
        System.out.println("微信服務(wù)更新消息: " + s);
        //消息更新,通知所有觀察者
        notifyObserver();
    }
}
  1. 定義具體觀察者,公眾號(hào)的具體觀察者為用戶User
/**
 * 觀察者
 * 實(shí)現(xiàn)了update方法
 */
public class User implements Observer {

    private String name;
    private String message;
    
    public User(String name) {
        this.name = name;
    }
    
    @Override
    public void update(String message) {
        this.message = message;
        read();
    }
    
    public void read() {
        System.out.println(name + " 收到推送消息: " + message);
    }
}
  1. 編寫(xiě)一個(gè)測(cè)試類(lèi)
    a. 首先注冊(cè)了三個(gè)用戶,ZhangSan、LiSi、WangWu。公眾號(hào)發(fā)布了一條消息"PHP是世界上最好用的語(yǔ)言!",三個(gè)用戶都收到了消息。
    b. 用戶ZhangSan看到消息后頗為震驚,果斷取消訂閱,這時(shí)公眾號(hào)又推送了一條消息,此時(shí)用戶ZhangSan已經(jīng)收不到消息,其他用戶還是正常能收到推送消息。
public class Test {
    public static void main(String[] args) {
        WechatServer server = new WechatServer();
        
        Observer userZhang = new User("ZhangSan");
        Observer userLi = new User("LiSi");
        Observer userWang = new User("WangWu");
        
        server.registerObserver(userZhang);
        server.registerObserver(userLi);
        server.registerObserver(userWang);
        server.setInfomation("PHP是世界上最好用的語(yǔ)言!");
        
        System.out.println("----------------------------------------------");
        server.removeObserver(userZhang);
        server.setInfomation("JAVA是世界上最好用的語(yǔ)言!");
  }
}

測(cè)試結(jié)果:


image.png

提示:本文知識(shí)引用來(lái)源于 JAVA設(shè)計(jì)模式之觀察者模式

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 觀察者模式的定義: 在對(duì)象之間定義了一對(duì)多的依賴,這樣一來(lái),當(dāng)一個(gè)對(duì)象改變狀態(tài),依賴它的對(duì)象會(huì)收到通知并自動(dòng)更新。...
    代碼之尖閱讀 663評(píng)論 0 51
  • 本文的結(jié)構(gòu)如下: 什么是觀察者模式 為什么要用該模式 模式的結(jié)構(gòu) 代碼示例 推模型和拉模型 優(yōu)點(diǎn)和缺點(diǎn) 適用環(huán)境 ...
    w1992wishes閱讀 1,526評(píng)論 0 16
  • 【學(xué)習(xí)難度:★★★☆☆,使用頻率:★★★★★】直接出處:觀察者模式梳理和學(xué)習(xí):https://github.com...
    BruceOuyang閱讀 1,680評(píng)論 1 5
  • 觀察者模式可以說(shuō)是眾多設(shè)計(jì)模式中,最容易理解的設(shè)計(jì)模式之一了,觀察者模式在Spring中也隨處可見(jiàn),面試的時(shí)候,面...
    CoderBear閱讀 2,481評(píng)論 0 6
  • 一場(chǎng)奢侈的陪伴。我們何時(shí)才明白那不屬于你我,它像鳥(niǎo)兒一樣,縈繞在你我的肩頭,心上,周邊,不屬于你我,卻無(wú)論如何都拋...
    胡白白閱讀 333評(píng)論 0 0

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