设计模式之观察者模式浅析

本来不想再写观察者模式的,但是在项目用到了几次。感觉实现功能之余,这种模式实现的代码太优雅了……一时冲动之下又想撸一篇文章,除了给自己总结之外,也想分享给大家。
观察者模式也叫做发布/订阅模型(Publish/Subscribe)。其官方(我也是再网上看到的定义,自己总结不了这么好)定义如下:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。通用UML类图:
这里写图片描述

角色分析
Subject:被观察者,它可以添加和删除观察者,并且推送消息给观察者
Observer:观察者,update方法接受被观察者投递来的消息,进行处理
ConcreteSubject:实现被观察者的逻辑,决定什么时候将消息投递给观察者
ConcreteObserver:实现观察者的逻辑,每个观察者实现的逻辑是不一样的,各个观察者有自己的逻辑
好了,各个角色我们大概明白了,那么在我的项目中是如何使用的呢?
场景
刚好前不久公司项目中有这么一个需求,就是采集运输车司机所行走过的轨迹。每隔一段时间会向服务器发送一次gps定位信息,最开始我用了一种很笨的方法,就是创建定时器,固定时间去拿一次gps信息。这种做法不是不可取,只是实现起来太LOw了,我们何不使用更优雅一点的方法呢。定时器其实已经有了,就是我们的定位模块,这里用的百度定位,百度定位是可设置回调时间的。我们可以换一种思路,不必总是去拿gps信息,而且一旦定位到了gps信息主动投递给上传方法,关系倒置一下换位思考。
大概实现如下:


 public final class LocatoinReceiver extends Observable implements BDLocationListener {
    //定位模块实现....


    //每次有定位回调,主动推送消息给订阅者
    @Override
    public void onReceiveLocation(BDLocation bdLocation) {
            setChanged();
            this.notifyObservers(bdLocation);
    }
 }

 public class TransportPresenterImpl implements Observer{
    @Override
    public void attchContext(Context context) {
        ……
        LocatoinReceiver.getInstance(mContext).addObserver(this);
    }
    @Override
    public void update(Observable observable, Object data) {
        //观察者自己的逻辑
    }

      @Override
    public void destroy() {
         LocatoinReceiver.getInstance(mContext).deleteObserver(this);
    }
 }

注意:这里我是配合着单利模式使用的,为了避免内存泄漏,请在生命周期结束的时候,一定要除去静态引用。。
设计模式让我的实现确实优雅了许多,比如说:项目中的“个人中心” 有积分,奖励等。。都是需要登录后的,没登录会去登录页,登录后改变各页面的状态,也可以使用观察者模式去实现,虽然我原来是通过广播,但是观察者实现起来更优雅,这里就不再累述了。

观察者模式的优点:观察者和被观察者之间是抽象耦合,如此设计,则不管是增加观察者还是被观察者都非常容易扩展,而且在Java中都已经实现的抽象层级的定义,在系统扩展方面更是得心应手。
缺点:效率问题,观察者模式需要考虑一下开发效率和运行效率问题,一个被观察者,多个观察者,开发 和调试就会比较复杂,而且在Java中消息的通知默认是顺序执行,一个观察者卡壳,会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。多级触发时的效率更是让人担忧,大家在设计时注意考虑。
以上。。

猜你喜欢

转载自blog.csdn.net/qq_23186653/article/details/51105158