成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

設(shè)計模式走一遍---觀察者模式(下)

aisuhua / 1511人閱讀

摘要:上篇我們講解了觀察者模式的一些知識,而且自定義觀察者模式的經(jīng)典代碼,傳送們設(shè)計模式走一遍觀察者模式上這篇簡單講一下自帶的觀察者模式實現(xiàn)代碼。注被觀察者又被稱為主題對象,目標(biāo)對象。

上篇我們講解了觀察者模式的一些知識,而且自定義觀察者模式的經(jīng)典代碼,(傳送們:設(shè)計模式走一遍---觀察者模式(上))

這篇簡單講一下JDK自帶的觀察者模式實現(xiàn)代碼。

對于觀察者模式,JDK中提供了一個Observer接口(觀察者),一個Observable類(主題對象)。

注:被觀察者又被稱為主題對象,目標(biāo)對象。

具體我們來看下源碼。

1.觀察者接口

public interface Observer {
    /**
     * This method is called whenever the observed *object is changed. 
     *當(dāng)被觀察者發(fā)生變化時,該方法將會被調(diào)用
     * @param   o     the observable object.
     * @param   arg   an argument passed to the notifyObservers
     *                 method.
     */
    void update(Observable o, Object arg);
}

該接口相當(dāng)于觀察者,里面有一個update(Observable o, Object arg)方法,Observable參數(shù)是指主題對象,該參數(shù)指明該觀察者是屬于哪一個主題對象的。

arg參數(shù)可以是任意對象,假如主題對象在發(fā)送通知時,想要傳遞什么數(shù)據(jù)給觀察者,那么就可以把數(shù)據(jù)對象傳遞給arg參數(shù)。

2.主題對象類(方法有點多,我就不放英文解釋了)

//主題對象可以是接口、抽象類、具體類,我們上節(jié)說
//一般采用抽象類,不過JDK這里使用的是具體類
public class Observable {
    //標(biāo)記主題對象的狀態(tài)是否改變
    private boolean changed = false;
    //存放觀察者集合,之所以用Vector而不用ArrayList
    //主要是Vector是線程安全的
    private Vector obs;

    public Observable() {
        obs = new Vector<>();
    }

    //添加一個觀察者
    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    //刪除一個觀察者
    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }
    
    //標(biāo)記該對象的狀態(tài)是否發(fā)送了改變
    protected synchronized void setChanged() {
        changed = true;
    }

    //指示該對象不會再發(fā)生改變,或者它已經(jīng)通知了
    //所有觀察者
    protected synchronized void clearChanged() {
        changed = false;
    }
    
    
    //測試對象是否發(fā)生了改變。當(dāng)且僅當(dāng)在此對象最近
    //調(diào)用了setChange()方法
    public synchronized boolean hasChanged() {
        return changed;
    }

    //如果hasChanged()方法指示此對象發(fā)送了改變,
    //則通知所有觀察者,并且調(diào)用clearChanged()方法
    //指示此對象不再改變
    public void notifyObservers() {
        notifyObservers(null);
    }

    //與上面沒有參數(shù)的同名方法相同,只是如果這個方
    //法的arg參數(shù)可以接受主題對象想要傳遞觀察者的數(shù)據(jù)對象
    public void notifyObservers(Object arg) {
        //臨時保存所有觀察者
        Object[] arrLocal;

        synchronized (this) {
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

    //刪除所有觀察者
    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    //返回觀察者的數(shù)量
    public synchronized int countObservers() {
        return obs.size();
    }
}

該具體類Observable相當(dāng)于主題對象,實現(xiàn)的主要功能就是當(dāng)自己的狀態(tài)發(fā)送改變時,通知觀察者,觀察者再根據(jù)通知,在update方法做出相應(yīng)的反應(yīng)。

簡單寫個Demo測試下。

public class Test {
    public static void main(String[] args){
        //創(chuàng)建一個主題對象
        AnimalSubject animalSubject = new AnimalSubject();
        animalSubject.addObserver(new DogObsever());
        animalSubject.addObserver(new LionObsever());
        //狀態(tài)發(fā)生改變
        animalSubject.setChanged();
        //通知觀察者
        animalSubject.notifyObservers();
    }
}

//動物主題,弄子類方便拓展主題對象功能
class AnimalSubject extends Observable{
    //不過我就不新增代碼、方法了

    //不覆蓋下的話,上面的測試調(diào)用不了setChange()方法
    //為了方便測試,覆蓋重寫下
    @Override
    protected synchronized void setChanged() {
        super.setChanged();
    }
}
class DogObsever implements Observer{
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("收到通知,小狗觀察者正在做出相應(yīng)處理");
    }
}

class LionObsever implements Observer{
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("收到通知,獅子觀察者正在做出相應(yīng)處理");
    }
}

打印結(jié)果

收到通知,獅子觀察者正在做出相應(yīng)處理
收到通知,小狗觀察者正在做出相應(yīng)處理

從上面的代碼中我們可以發(fā)現(xiàn)JDk內(nèi)置的觀察者模式中的主題對象是一個具體類,而不是一個抽象類或接口,而且setChange()方法還被保護起來了(被定義為protected),這就意味著,要在別的類中調(diào)用該方法,那么我們必須繼承在子類中重寫覆蓋該方法。顯然,我覺得這很不友好.....

可能這也是JDK內(nèi)置的觀察者模式很少被拿來使用 的原因吧,一般都是自己來自定義觀察者模式。

希望大家能夠動手寫一下這些代碼,可能會碰到一些你沒想到的問題。

關(guān)注公我的眾號:苦逼的碼農(nóng),獲取更多原創(chuàng)文章,后臺回復(fù)禮包送你一份時下熱門的資源大禮包。同時也感謝把文章介紹給更多需要的人

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/77020.html

相關(guān)文章

  • 設(shè)計模式一遍---察者模式

    摘要:觀察者模式的別名包括發(fā)布訂閱模式模型視圖模式源監(jiān)聽器模式或從屬者模式。而觀察者一般也會做出對象的響應(yīng)觀察者模式屬于行為型模式觀察者模式主要解決的問題一方的狀態(tài)發(fā)生了變化,依賴于這一方的觀察者立即能收到通知。參考書籍設(shè)計模式版。 1 紅燈車過,人停;綠燈人過,車停。每天走在馬路上,到處可見紅綠燈指揮著我們什么時候可以過馬路,什么時候不能過馬路。無論是人還是車,都時刻關(guān)注著紅綠燈的狀態(tài),一...

    justCoding 評論0 收藏0
  • 簡單 16步一遍 Laravel Echo 的使用

    摘要:在國內(nèi),個人還是不推薦使用,訪問速度有所影響,而且其還是一個商業(yè)產(chǎn)品。今天利用最簡便的步,走一遍代碼集成和來使用。代碼簡單創(chuàng)建監(jiān)聽我們在后端添加一個被創(chuàng)建的事件,并繼承。 showImg(https://segmentfault.com/img/remote/1460000015801244?w=904&h=241); 先飚幾句英文,說說 Laravel Echo 的作用: One o...

    chavesgu 評論0 收藏0
  • 移動測試中游戲和應(yīng)用的不同之處

    摘要:今天就說說移動測試中最重要的兩個方向。自動化測試完全不同于手游自動化測試手機和手游的開發(fā)技術(shù)不同,這導(dǎo)致了兩者的自動化測試技術(shù)是截然不同的。手游和的第二個玩法不同在于探索性。 隨著智能設(shè)備的普及和移動互聯(lián)網(wǎng)的興起,各家互聯(lián)網(wǎng)巨頭紛紛在往移動端布局和轉(zhuǎn)型,同時初創(chuàng)的移動互聯(lián)網(wǎng)公司也都盯著這個市場希望分一杯羹。在這個大環(huán)境下,互聯(lián)網(wǎng)的重心已經(jīng)慢慢從Web端轉(zhuǎn)向了移動端,而移動端的軟件測試也...

    Jinkey 評論0 收藏0
  • 項目開發(fā)的責(zé)任感

    摘要:目前我形成了一個項目告一段落就進行一次總結(jié)的習(xí)慣,總結(jié)會對提高自己的思維層次和能力都非常的有幫助,這篇文章主要基于我現(xiàn)在所在的環(huán)境,和所在的公司情景來寫的關(guān)于開發(fā)開發(fā)過程,我制作了流程化,從文檔入手,做數(shù)據(jù)結(jié)構(gòu)分析數(shù)據(jù)表結(jié)構(gòu)分析程序結(jié)構(gòu)分析 目前我形成了一個項目告一段落就進行一次總結(jié)的習(xí)慣,總結(jié)會對提高自己的思維層次和能力都非常的有幫助,這篇文章主要基于我現(xiàn)在所在的環(huán)境,和所在的公司...

    NickZhou 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<