觀察者模式——消息訂閱模式?

一、基礎簡介

1、定義

定義了一種一對多的依賴關(guān)系,讓多個觀察者對象同時監(jiān)聽某一個主題對象,當主題對象的狀態(tài)發(fā)生改變時,會通知所有觀察者對象,使他們能夠自動更新自己。觀察者模式屬于行為型模式。

2、使用場景

當一個對象的改變需要同時改變其他對象,而且它不知道具體有多少對象有待改變時(解耦),可以考慮使用觀察者模式。

3、優(yōu)缺點

優(yōu)點: 1、觀察者和被觀察者是抽象耦合的。 2、建立一套觸發(fā)機制。

缺點: 1、如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。 2、如果在觀察者和觀察目標之間有循環(huán)依賴的話,觀察目標會觸發(fā)它們之間進行循環(huán)調(diào)用,可能導致系統(tǒng)崩潰。 3、觀察者模式?jīng)]有相應的機制讓觀察者知道所觀察的目標對象是怎么發(fā)生變化的,而僅僅只是知道觀察目標發(fā)生了變化。

4、模式結(jié)構(gòu)

  1. 抽象主題(Subject)角色:也叫抽象目標類,它提供了一個用于保存觀察者對象的聚集類和增加、刪除觀察者對象的方法,以及通知所有觀察者的抽象方法。
  2. 具體主題(Concrete Subject)角色:也叫具體目標類,它實現(xiàn)抽象目標中的通知方法,當具體主題的內(nèi)部狀態(tài)發(fā)生改變時,通知所有注冊過的觀察者對象。
  3. 抽象觀察者(Observer)角色:它是一個抽象類或接口,它包含了一個更新自己的抽象方法,當接到具體主題的更改通知時被調(diào)用。
  4. 具體觀察者(Concrete Observer)角色:實現(xiàn)抽象觀察者中定義的抽象方法,以便在得到目標的更改通知時更新自身的狀態(tài)。

二、代碼實例

1、UML類圖

2、Subject 抽象目標類:通知者

package com.mfc.design.觀察者模式;

import java.util.ArrayList;
import java.util.List;

/**
 * @author MouFangCai
 * @date 2019/10/16 10:39
 *
 * 抽象通知者
 */
public class Subject {

    private String subjectName;

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

    public void attach(Observer observer) {
        observers.add(observer);
    }

    public void detach(Observer observer) {
        observers.remove(observer);
    }

    public void notifyAllObserver(String newState){
        for (Observer ob : observers) {
                ob.update(newState );
        }
    }

    public String getSubjectName() {
        return subjectName;
    }

    public void setSubjectName(String subjectName) {
        this.subjectName = subjectName;
    }
}

3、ConcreteSubject 具體通知者

package com.mfc.design.觀察者模式;

/**
 * @author MouFangCai
 * @date 2019/10/16 10:44
 *
 * 具體通知者
 */
public class ConcreteSubject extends Subject {

    private String state;

    public ConcreteSubject(String name) {
        setSubjectName(name);
    }

    public void change(String newState) {
        this.state = state;

        notifyAllObserver(newState);
    }
}

4、Observer:抽象觀察者

package com.mfc.design.觀察者模式;

/**
 * @author MouFangCai
 * @date 2019/10/16 10:33
 *
 * 抽象觀察者
 */
public abstract class Observer {

    private String name;
    private Subject subject;
    abstract void update(String newState);

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Subject getSubject() {
        return subject;
    }

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

5、ConcreteObserver:具體觀察者

package com.mfc.design.觀察者模式;

/**
 * @author MouFangCai
 * @date 2019/10/16 10:36
 *
 * 具體觀察者
 */
public class ConcreteObserver1 extends Observer {

    public ConcreteObserver1(String name, Subject subject) {
        this.setName(name);
        this.setSubject(subject);
    }

    @Override
    public void update(String newState) {

        System.out.println("觀察者:" + this.getName() + "——收到[" + this.getSubject().getSubjectName() + "]通知{"+newState +"},改變狀態(tài)");
    }
}

package com.mfc.design.觀察者模式;

/**
 * @author MouFangCai
 * @date 2019/10/16 10:36
 *
 * 具體觀察者
 */
public class ConcreteObserver2 extends Observer {

    public ConcreteObserver2(String name, Subject subject) {
        this.setName(name);
        this.setSubject(subject);
    }

    @Override
    public void update(String newState) {

        System.out.println("觀察者:" + this.getName() + "——收到[" + this.getSubject().getSubjectName() + "]通知{"+newState +"},改變狀態(tài)");

    }
}

6、客戶端測試

package com.mfc.design.觀察者模式;

/**
 * @author MouFangCai
 * @date 2019/10/16 14:09
 */
public class Client_Observer {

    public static void main(String[] args) {
        Subject subject = new ConcreteSubject("通知者");
        ConcreteObserver1 observer1 = new ConcreteObserver1("觀察者1", subject);
        ConcreteObserver2 observer2 = new ConcreteObserver2("觀察者2", subject);

        subject.attach(observer2);
        subject.attach(observer1);
        subject.notifyAllObserver("消息來了");

    }
}

7、結(jié)果分析

觀察者:觀察者2——收到[通知者]通知{消息來了},改變狀態(tài)
觀察者:觀察者1——收到[通知者]通知{消息來了},改變狀態(tài)

Process finished with exit code 0

對于“觀察者模式”簡單理解就是:放風,一個哨兵(Subject)觀察情況,發(fā)現(xiàn)情況就“按鈴”通知,具體通知哪些,哨兵也不知道,只有時刻關(guān)注“鈴鐺”的觀察者(ConcreteObserver)才會收到消息,做出相應的改變

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

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