Java-觀察者模式(訂閱-發(fā)布者模式)

定義

觀察者模式也叫訂閱-發(fā)布者模式,是一種一對(duì)一或者一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象改變狀態(tài),依賴它的對(duì)象會(huì)收到通知并自動(dòng)更新。

觀察者模式的結(jié)構(gòu)

觀察者模式主要由四個(gè)主要部分構(gòu)成
(1)主題(Subject):主題也叫抽象被觀察者,是一個(gè)接口,該接口規(guī)定了具體主題需要實(shí)現(xiàn)的方法,比如,添加、刪除觀察者以及通知觀察者更新數(shù)據(jù)的抽象方法。
(2)觀察者(Observer):觀察者是一個(gè)接口,該接口規(guī)定了具體觀察者用來更新數(shù)據(jù)的方法。
(3)具體主題(ConcreteSubject):具體主題也叫具體被觀察者,是實(shí)現(xiàn)主題接口類的一個(gè)實(shí)例,該實(shí)例包含有可以經(jīng)常發(fā)生變化的數(shù)據(jù)。具體主題需使用一個(gè)集合,比如ArrayList,存放觀察者的引用,以便數(shù)據(jù)變化時(shí)及時(shí)通知具體觀察者。
(4)具體觀察者(ConcreteObserver):實(shí)現(xiàn)抽象觀察者角色所需要的更新接口,對(duì)具體主題通知做出改變。

通俗點(diǎn)就是:主題發(fā)布信息,觀察者獲取信息,他們關(guān)聯(lián)了就能收到信息,沒有關(guān)聯(lián)就收不到信息。
如圖:

image.png

觀察者模式的適用的場(chǎng)景

如果你想一個(gè)對(duì)象的數(shù)據(jù)更新時(shí)需要通知其他對(duì)象,讓其他對(duì)象對(duì)通知做出改變,那么觀察者模式比較實(shí)用。

代碼部分

場(chǎng)景:假設(shè)張三和李四買彩票,時(shí)刻關(guān)注彩票中心的消息,其中一個(gè)人中獎(jiǎng),很高興,另一個(gè)人不開心,取消了對(duì)彩票中心的關(guān)注,就再也收不到彩票中心的消息了。
在這個(gè)模擬中彩票中心就是主題(Subject),張三和李四就是觀察彩票中心消息的具體觀察者(ConcreteObserver)。對(duì)彩票消息做出行為。

Subject接口相關(guān)代碼

/**
 * 描述:抽象主題(抽象被觀察者)
 */
public interface Subject {
    /**
     * 注冊(cè)觀察者
     * @param observer 觀察者
     */
     void registerObserver(Observer observer);

    /**
     * 移除觀察者
     * @param observer 觀察者
     */
     void removeObserver(Observer observer);

    /**
     * 在狀態(tài)發(fā)生變化通知觀察者
     */
    void notifyObserver(String message);
}

Observer接口相關(guān)代碼

/**
 * 描述:抽象觀察者
 */
public interface Observer {
    /**
     * 當(dāng)被觀察者調(diào)用notifyObservers()方法時(shí),觀察者的update()方法會(huì)被回調(diào)。
     * @param message 通知內(nèi)容
     */
     void update(ConcreteObserver observer,String message);
}

ConcreteSubject類相關(guān)代碼

/**
 * 描述:具體主題實(shí)現(xiàn)類
 */
public class ConcreteSubject implements Subject {


    //創(chuàng)建集合用來存放觀察者對(duì)象
    List<Observer> mObserverList;



    public ConcreteSubject() {
       mObserverList = new LinkedList<>();
    }

    //注冊(cè)觀察者,也就是將觀察者放到集合中
    @Override
    public void registerObserver(Observer observer) {
        mObserverList.add(observer);

    }


    //移除觀察者,也就是將觀察者從集合中移除
    @Override
    public void removeObserver(Observer observer) {
            mObserverList.remove(observer);

    }


    //狀態(tài)改變,通知觀察者
    @Override
    public void notifyObserver(String message) {
        //遍歷通知所有觀察者
        for(int i =0;i<mObserverList.size();i++){
            //此處進(jìn)行了強(qiáng)轉(zhuǎn)
            mObserverList.get(i).update((ConcreteObserver)mObserverList.get(i),message);
        }

    }


    /**
     * 通知內(nèi)容
     * @param message
     */
    public void sendMessage(String message){
        notifyObserver(message);
    }


}

ConcreteObserver類相關(guān)代碼

/**
 * 描述:具體觀察者,對(duì)Subject的通知執(zhí)行具體操作
 */
public class ConcreteObserver implements Observer {
    private static final String TAG = "ConcreteObserver";
    //用戶名
   String name;
   //中獎(jiǎng)號(hào)碼
    String number;

    public ConcreteObserver(String name,String work) {
        this.name = name;
        this.number=work;
    }

    @Override
    public void update(ConcreteObserver observer,String message) {
        if(observer.number.equals(message)){
            Log.e(TAG, observer.name+"的號(hào)碼是:" +observer.number+"中獎(jiǎng)號(hào)碼是"+message+"他很高興");
        }else{
            Log.e(TAG, observer.name+"的號(hào)碼是:" +observer.number+"中獎(jiǎng)號(hào)碼是"+message+"不很高興");
        }
    }


}

測(cè)試相關(guān)代碼

    //創(chuàng)建主題實(shí)例
        ConcreteSubject concreteSubject =new ConcreteSubject();

        ConcreteObserver zhansan =new ConcreteObserver("張三","111111");
        ConcreteObserver lisi  =new ConcreteObserver("李四","222222");

        concreteSubject.registerObserver(zhansan);
        concreteSubject.registerObserver(lisi);

        //設(shè)置中獎(jiǎng)號(hào)碼
        concreteSubject.sendMessage("111111");

        //移除觀察者李四
        concreteSubject.removeObserver(lisi);
        //設(shè)置中獎(jiǎng)號(hào)碼
        concreteSubject.sendMessage("222222");

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

image.png

雖然現(xiàn)在觀察者模式不常用了,更多人選擇Rx等框架實(shí)現(xiàn)即時(shí)更新,但我們一定要理解其本質(zhì)和核心思想。

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

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

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