23天學(xué)習(xí)23種設(shè)計(jì)模式——觀察者模式

前言

在日常生活中,比如我們訂閱報(bào)紙或者訂牛奶?;蛘咴诰W(wǎng)絡(luò)上,RSS方式訂閱別人的博客,微博follow某人,以及現(xiàn)在很火的即刻app。都是采取的訂閱的模式。當(dāng)我們需要報(bào)紙,牛奶,以及查看別人博客/微博,或是某種主題的消息,我們只需采取訂閱的方式在發(fā)布方注冊一下即可。當(dāng)我們不需要的時候,只要取消訂閱就可以了。在軟件開發(fā)中,同樣有利用這種原理的設(shè)計(jì)模式——觀察者模式。

是什么

觀察者模式(Observer Pattern):定義對象之間的一種一對多依賴關(guān)系,使得每當(dāng)一個對象狀態(tài)發(fā)生改變時,其相關(guān)依賴對象都得到通知并被自動更新。

觀察者模式的別名包括發(fā)布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監(jiān)聽器(Source/Listener)模式或從屬者(Dependents)模式。觀察者模式是一種對象行為型模式。

下圖就是觀察者模式結(jié)構(gòu)圖:

有如下角色:

  • Subject: 目標(biāo)
  • ConcreteSubject:具體目標(biāo)
  • Observer: 觀察者
  • ConcreteObserver:具體觀察者
觀察者模式結(jié)構(gòu)圖

為什么

還是以日常生活舉例,當(dāng)我們想要查看某人的博客是否有更新的時候。我們可以直接在瀏覽器中輸入博客地址進(jìn)行查看。但是這樣一種方式,往往效率不高。有可能幾天內(nèi)都沒有更新。但是如果我們采用RSS方式訂閱的話,我們能在第一事件收到對方博客更新的消息。其他時候,我們可以處理別的事物,而不用主動查看是否有更新。同理,在軟件開發(fā)中。一些對象如果對對象A的狀態(tài)的變化感興趣,采用觀察者模式來訂閱它的狀態(tài)更新,這樣就不用持有對象A的引用了。降低了對象之間的耦合。

怎么做

首先是主題Subject類的實(shí)現(xiàn),它使用集合持有訂閱者,訂閱者通過attach方法訂閱主題,detach方法取消訂閱,當(dāng)主題的state發(fā)生變化時,通過notifyObservers通知訂閱者,主題狀態(tài)有更新:

/**
 * 主題,被觀察對象
 */
public class Subject {

    private List<Observer> observers = new ArrayList<>();//訂閱者鏈表

    private int state;//主題狀態(tài)

    public void attach(Observer observer){
        if(observer!=null){
            observers.add(observer);
        }
    }

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

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyObservers();
    }

    public void notifyObservers(){
        for(Observer observer:observers){
            observer.update(this);
        }
    }
}


然后時訂閱者類的實(shí)現(xiàn),一般是一個抽象類或者接口:

/**
 * 觀察者
 */
public interface Observer {

    void update(Subject subject);

}

接著時具體觀察者類的實(shí)現(xiàn),在update方法中對主題狀態(tài)改變進(jìn)行具體操作:

public class BinaryObserver implements Observer {
    @Override
    public void update(Subject subject) {
        System.out.println("Binary String:"+Integer.toBinaryString(subject.getState()));
    }
}

public class HexObserver implements Observer {
    @Override
    public void update(Subject subject) {
        System.out.println("Hex String:"+Integer.toHexString(subject.getState()));
    }
}

public class OctalObserver implements Observer {
    @Override
    public void update(Subject subject) {
        System.out.println("Octal String:"+Integer.toOctalString(subject.getState()));
    }
}

最后,我們寫個Client類看看具體應(yīng)用:

public class Client {
    public static void main(String[] args) {

        Subject subject = new Subject();

        HexObserver hexObserver = new HexObserver();
        OctalObserver octalObserver = new OctalObserver();
        BinaryObserver binaryObserver = new BinaryObserver();

        //觀察者訂閱主題
        subject.attach(hexObserver);
        subject.attach(octalObserver);
        subject.attach(binaryObserver);

        System.out.println("Set state:15");
        subject.setState(15);//設(shè)置狀態(tài)

        System.out.println("-----------------");
        //取消訂閱主題
        subject.detach(octalObserver);
        System.out.println("Set state:24");
        subject.setState(24);//改變狀態(tài)


    }
}

運(yùn)行結(jié)果:


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

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

  • 1 場景問題# 1.1 訂閱報(bào)紙的過程## 來考慮實(shí)際生活中訂閱報(bào)紙的過程,這里簡單總結(jié)了一下,訂閱報(bào)紙的基本流程...
    七寸知架構(gòu)閱讀 4,814評論 5 57
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,355評論 25 708
  • 純粹是個人學(xué)習(xí)總結(jié),如有不對的地方請吐槽。 設(shè)計(jì)模式參考地址:http://www.cnblogs.com/mao...
    junwu_123閱讀 765評論 0 0
  • 設(shè)計(jì)模式匯總 一、基礎(chǔ)知識 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 4,096評論 1 15
  • 今天已是8月最后一篇作業(yè),每次都是交作業(yè)這天,下午四點(diǎn)準(zhǔn)時敲鍵盤。 如果有已經(jīng)構(gòu)思好的話題,那敲起來很順利,啪啪幾...
    少東閱讀 442評論 0 2

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