觀察者模式在Java項目中的運用


文中項目代碼鏈接:https://github.com/BadWaka/WakaPedometer

一.觀察者模式簡介

1.定義:觀察者模式(有時又被稱為模型-視圖(View)模式、源-收聽者(Listener)模式或從屬者模式)是軟件設計模式的一種。在此種模式中,一個目標物件管理所有相依於它的觀察者物件,並且在它本身的狀態改變時主動發出通知。這通常透過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實現事件處理系統。

2.三要素:觀察者,被觀察者,事件「訂閱」。

3.UML圖:

其實,說白了,觀察者模式就是一個一對多的消息的發布訂閱關系。在這個模式中,通常是有一個被觀察者,我們可以把它理解為消息的發布者;若干個觀察者,可以理解為消息的訂閱者。舉一個生活中的例子:微信公眾號,大家一定或多或少的都關注過幾個微信公眾號,每次公眾號發布的內容有更新的時候,訂閱號頁面里都會將這個公眾號置頂並加紅點提示。這就是一個典型的觀察者模式的應用。一個公眾號就是一個被觀察者,用戶通過訂閱操作與被觀察者建立聯系,這個用戶就成了觀察者。

 

二.Java中的觀察者模式及具體應用

1.Java中的觀察者模式簡介:

在Java中,要應用觀察者模式,觀察者要實現java.util.Observer接口;被觀察者要繼承java.util.Observable類。

在這個基礎上,觀察者要重寫Observer接口中的update()方法。觀察者向被觀察者訂閱事件是通過調用addObservers()方法來實現的。

2.觀察者和被觀察者的簡單代碼

(1)觀察者

//觀察者,需要用到觀察者模式的類需實現此接口
public interface Observer{
    void update(Object...objs);
}

(2)被觀察者

public abstract class Observable<T> {

    public final ArrayList<T> observerList = new ArrayList<>();
             //注冊觀察者對象
       public void registerObserver(T t) {
        checkNull(t);
        observerList.add(t);
    }
            //注銷觀察者對象
    public void unRegisterObserver(T t) {
        checkNull(t);
        observerList.remove(t);
    }
           //判斷觀察者對象是否為空
       private void checkNull(T t) {
        if (t == null) {
            throw new NullPointerException();
        }
    }
           //通知觀察者
       public abstract void notifyObservers(Object... objects);
}    

3.觀察者模式在Java中的應用實例

以下實例是在一個AndroidAPP中實現一個計步器功能。在Service類中有一個步數變量step,Activity類中需要動態監聽step變量的變化,並根據其更新UI。由於這個功能中用到了發布訂閱,所以應使用觀察者模式。在這里Activity為觀察者,Service為被觀察者。

(1)觀察者代碼:

//觀察者實現Observer接口並重寫update()方法。
public class PedometerFragment extends Fragment implements Observer {

    @Override
    public void update(Observable observable, Object data) {

    }
}

(2)被觀察者代碼:

//被觀察者繼承Observable類
public class StepObservable extends Observable {

    //單例
    private static StepObservable instance = null;

    public static StepObservable getInstance() {

        if (null == instance) {
            instance = new StepObservable();
        }

        return instance;
    }

    //通知觀察者更新數據
    public void notifyStepChange(int step) {

        setChanged();//設置changeFlag
        notifyObservers(step);//通知觀察者
    }

}

(3)訂閱事件

//觀察者調用addObserver()向被觀察者訂閱事件
//項目中,這個步驟添加到Activity類的onResume()函數中
public void onResume() {
        super.onResume();

        //訂閱操作
        StepObservable.getInstance().addObserver(this);
    }

(4)更新數據

//被觀察者Service更新
private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

        //..

        //得到當前步數
        currentStep = step;

        //由於步數改變,被觀察者更新數據
        StepObservable.getInstance().notifyStepChange(currentStep);

        //..

    }
}


//觀察者Activity更新
@Override
//收到notifyObservers()方法的通知,調用update()函數,更新數據
    public void update(Observable observable, Object data) {

        int step = (int) data;
        Snackbar.make(roundProgressBar, "step=" + step, Snackbar.LENGTH_SHORT).show();
        Log.i(TAG, "step=" + step);
    }

(5)取消訂閱

//在Activity中的onpause()方法中實現取消訂閱的代碼
@Override
    public void onPause() {
        super.onPause();

        //觀察者從被觀察者隊列中移除
        StepObservable.getInstance().deleteObserver(this);
    }

 

三.總結

綜上所述,Java編程中需要大量應用觀察者模式的模型。觀察者模式作為一種十分常用的設計模式,為我們的編寫程序提供了便利。最后想總結一下觀察者模式的優缺點。

優點:觀察者與被觀察者之間是一個輕度的關聯關系,體現了模塊的高內聚,低耦合。因此對於觀察者和被觀察者來說,要進行擴展就比較簡單了。被觀察者並不需要認識任何一個具體的觀察者。它只需要提供一個觀察者共同的接口即可。提高代碼的可復用性。

缺點:在狀態變化,觀察者通知被觀察者的時候,如果觀察者過多,那么可能導致消息的傳送失去實時性。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM