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

來源:互聯網
上載者:User

上篇我們講解了觀察者模式的一些知識,而且自訂觀察者模式的經典代碼,(傳送們:設計模式走一遍—-觀察者模式(上))

這篇簡單講一下JDK內建的觀察者模式實現代碼。

對於觀察者模式,JDK中提供了一個Observer介面(觀察者),一個Observable類(主題對象)。

註:被觀察者又被稱為主題對象,目標對象。

具體我們來看下源碼。

1.觀察者介面

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

該介面相當於觀察者,裡面有一個update(Observable o, Object arg)方法,Observable參數是指主題對象,該參數指明該觀察者是屬於哪一個主題對象的。

arg參數可以是任意對象,假如主題對象在發送通知時,想要傳遞什麼資料給觀察者,那麼就可以把資料對象傳遞給arg參數。

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

//主題對象可以是介面、抽象類別、具體類,我們上節說//一般採用抽象類別,不過JDK這裡使用的是具體類public class Observable {    //標記主題對象的狀態是否改變    private boolean changed = false;    //存放觀察者集合,之所以用Vector而不用ArrayList    //主要是Vector是安全執行緒的    private Vector<Observer> 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);    }    //標記該對象的狀態是否發送了改變    protected synchronized void setChanged() {        changed = true;    }    //指示該對象不會再發生改變,或者它已經通知了    //所有觀察者    protected synchronized void clearChanged() {        changed = false;    }    //測試對象是否發生了改變。若且唯若在此對象最近    //調用了setChange()方法    public synchronized boolean hasChanged() {        return changed;    }    //如果hasChanged()方法指示此對象發送了改變,    //則通知所有觀察者,並且調用clearChanged()方法    //指示此對象不再改變    public void notifyObservers() {        notifyObservers(null);    }    //與上面沒有參數的同名方法相同,只是如果這個方    //法的arg參數可以接受主題對象想要傳遞觀察者的資料對象    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();    }    //返回觀察者的數量    public synchronized int countObservers() {        return obs.size();    }}

該具體類Observable相當於主題對象,實現的主要功能就是當自己的狀態發送改變時,通知觀察者,觀察者再根據通知,在update方法做出相應的反應。

簡單寫個Demo測試下。

public class Test {    public static void main(String[] args){        //建立一個主題對象        AnimalSubject animalSubject = new AnimalSubject();        animalSubject.addObserver(new DogObsever());        animalSubject.addObserver(new LionObsever());        //狀態發生改變        animalSubject.setChanged();        //通知觀察者        animalSubject.notifyObservers();    }}//動物主題,弄子類方便拓展主題對象功能class AnimalSubject extends Observable{    //不過我就不新增代碼、方法了    //不覆蓋下的話,上面的測試調用不了setChange()方法    //為了方便測試,覆蓋重寫下    @Override    protected synchronized void setChanged() {        super.setChanged();    }}class DogObsever implements Observer{    @Override    public void update(Observable o, Object arg) {        System.out.println("收到通知,小狗觀察者正在做出相應處理");    }}class LionObsever implements Observer{    @Override    public void update(Observable o, Object arg) {        System.out.println("收到通知,獅子觀察者正在做出相應處理");    }}

列印結果

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

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

可能這也是JDK內建的觀察者模式很少被拿來使用 的原因吧,一般都是自己來自訂觀察者模式。

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

關注公我的眾號:苦逼的碼農,擷取更多原創文章,後台回複禮包送你一份時下熱門的資源大禮包。同時也感謝把文章介紹給更多需要的人

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.