观察者模式在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编程中需要大量应用观察者模式的模型。观察者模式作为一种十分常用的设计模式,为我们的编写程序提供了便利。最后想总结一下观察者模式的优缺点。

优点:观察者与被观察者之间是一个轻度的关联关系,体现了模块的高内聚,低耦合。因此对于观察者和被观察者来说,要进行扩展就比较简单了。被观察者并不需要认识任何一个具体的观察者。它只需要提供一个观察者共同的接口即可。提高代码的可复用性。

缺点:在状态变化,观察者通知被观察者的时候,如果观察者过多,那么可能导致消息的传送失去实时性。

 

posted @ 2018-10-22 16:25  安中琪  阅读(3371)  评论(0编辑  收藏  举报