文中项目代码链接: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编程中需要大量应用观察者模式的模型。观察者模式作为一种十分常用的设计模式,为我们的编写程序提供了便利。最后想总结一下观察者模式的优缺点。
优点:观察者与被观察者之间是一个轻度的关联关系,体现了模块的高内聚,低耦合。因此对于观察者和被观察者来说,要进行扩展就比较简单了。被观察者并不需要认识任何一个具体的观察者。它只需要提供一个观察者共同的接口即可。提高代码的可复用性。
缺点:在状态变化,观察者通知被观察者的时候,如果观察者过多,那么可能导致消息的传送失去实时性。