Android使用的设计模式1——观察者模式

来源:互联网 发布:淘宝手机详情卖家推荐 编辑:程序博客网 时间:2024/06/05 00:44

观察者模式

**我们在面试过程中经常被问到,其实在项目开发过程中我们都会用到的,只是你没有注意到,今天我们就来分析一下:
观察者模式对于做系统或者做公共库的朋友来说,应该很熟悉,基本上所有系统都会用到这个模式。整理的时候,主要是对模式进行进步讲解然后结合Android里面应用进行说明。设计模式的说明主要是参考(设计模式解析与实战)如果对设计模式不了解的朋友,可以看看《设计模式解析与实战》这本书。**

 结合Android源码的时候,主要是针对应用层的代码说明,而且尽量使用简单例子代码,所以不会出现太多Android系统级的代码,大部分是我们做APP开发时会编写的代码。

  这篇文章不会详细介绍设计模式,只是整理设计模式核心概念,结合Android应用说明。

1、观察者模式

  观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式最常用在我们熟悉的事件驱动模型里面,像VC、Android界面里面的事件响应,就是基于观察者模式来实现。

  下面我们看看观察者模式的类图关系(图片是截取《研磨设计模式》里面插图):
  这里写图片描述

  • Subject是我们定义目标对象,或者说被观察对象。
  • ConcreteSubject是实际的被观察对象。
  • Observer是观察者的接口,定义了回调接口。
  • ConcreteObserver是实际的观察者对象。

2、观察者模式含义

  下面讲解一下个人对观察者模式的理解,其实这个模式在我们平时工作中是很常用的模式,可能你已经使用过,缺没有意识到。

  观察者模式主要是针对一对多的数据更新。简单来说就是,系统里面某个元素更新了数据,然后有好几个元素是使用了这个元素的数据。此时更新了数据的对象,就要通知其他使用了它数据的对象,让他们都进行更新。

  标准的观察者对象是一对多的关系,不过我们都知道设计模式里面是很灵活,在我们使用的时候,经常需要进行变形。对现有的标准模式进行适当的修改来适应设计需求。

  在我们实际应用中,还会遇到一对一、或者多对一的情况。一对一就是,一个目标对应一个观察者。多对一是指多个目标对应一个观察者。

3、观察者模式的简单实现

  下面给出一个最简单的观察者模式实现代码,把代码看懂了,再回头看文字讲解,会比较容易理解。下面是目标对象的接口和实现代码,只做了一个最简单的接口。
  

   //目标对象接口    public interface Subject    {        //调用这个方法注册一个新的观察者对象        public void attach(Observer observer);        //调用这个方法删除一个已注册的观察者对象        public void detach(Observer observer);        //调用这个方法通知所有注册的观察者对象        void notifyObservers();    }      //目标对象实现    public class ConcreteSubject implements Subject    {    //向量容器,保存所有注册的观察者        private Vector observersVector = new Vector();        public void attach(Observer observer)        {            observersVector.addElement(observer);        }        public void detach(Observer observer)        {            observersVector.removeElement(observer);        }        public void notifyObservers()        {            Enumeration enumeration = observers();            while(enumeration.hasMoreElements())            {                ((Observer)enumeration.nextElement()).update();            }        }    } 

下面是观察者的实现:

   //观察者接口    public interface Observer    {        void update();    }    //观察者实现    public class ConcreteObserver implements Observer    {        public void update()        {            System.out.println("The subject has changed! mythou notify");        }    }

应用中使用的代码:

  //客户端    public class Client    {        private static ConcreteSubject subject;        private static Observer observer;        public static void main(String args[])        {            //创建目标对象            subject = new ConcreteSubject();            //创建观察者对象            observer = new ConcreteObserver();            subject.attach(observer);            subject.change("mythou has changed data!");        }    }

4、Android 应用开发中的观察者模式

  在我们做Android应用的时候,会大量使用观察者模式,因为Framework层里面的事件驱动都是基于观察者模式实现的。另外在Framework层里面的各种服务在数据变更的时候,也是通过观察者模式实现上层数据更新。下面会讲两个例子来说明:

A)控件中Listener监听方式

  Android里面最典型的观察者就是我们使用的各种控件监听者。例如下面对某个按钮的监听:
  

Button baiduclickButton = (Button)findViewById(R.id.button1);//注册观察者baiduclickButton.setOnClickListener(new OnClickListener(){  //观察者实现    @Override    public void onClick(View arg0)    {        Log.d("Mythou_Log", "Click the button ");    }});

例如上面的代码,注册了一个按钮的监听方法。这里实际上是应用了一对一的观察者模式,setOnClickListener()方法就是注册一个观察者,Button对象就是我们要观察的目标对象。而new出来的OnClickListener(),就是我们实际的观察者。

  每当我们的目标按钮对象被点击,状态发生变化的时候,就会通过回调注册的OnClickListener观察者的onClick方法会来通知观察者,Button状态发生变化。这里的onClick相当于前面例子里面的update方法。下面是Android源码里面对OnClickListener的定义,跟我们前面定义一个观察者接口类似。

 public interface OnClickListener     {        /**         * Called when a view has been clicked.         *         * @param v The view that was clicked.         */        void onClick(View v);    }

B)GPS位置信息监听

  上面对按钮监听是属于一对一的观察者模式,当然你也可以用一个Listener监听多个按钮。下面我们再讲一个标准的一对多的观察者模式的应用。在我们使用GPS模块的时候,需要监听GPS模块位置变化,通常我们会编写下面代码:

// 通过GPS定位String LocateType= locationManager.GPS_PROVIDER;Location location = locationManager.getLastKnownLocation(LocateType);// 设置监听器,设置自动更新间隔这里设置1000ms,移动距离:0米。locationManager.requestLocationUpdates(provider, 1000, 0, locationListener);// 设置状态监听回调函数。statusListener是监听的回调函数。locationManager.addGpsStatusListener(statusListener); //监听器实现private final GpsStatus.Listener statusListener = new GpsStatus.Listener() {    public void onGpsStatusChanged(int event)   {      // GPS状态变化时的回调,获取当前状态      GpsStatus status = locationManager.getGpsStatus(null);    //自己编写的方法,获取卫星状态相关数据       GetGPSStatus(event, status);    }};

GPS位置服务是Framework的一个系统层服务,整个系统只有一个运行的实例。但实际使用时,可能会出现好几个应用都在使用这个服务,因此会形成了一个一对多的观察者例子。这里不对代码进行深入对比讲解,只要对照上面的讲解,你就可以把目标对象、观察者接口、观察者实现、数据更新回调接口找出来。有兴趣的朋友还可以追查Android的源码,看看GpsStatus里面的具体实现。

5、结语

  除了上面说的按钮响应、GPS服务外,还有一个例子比较经典,就是我们的BroadcastReceiver响应,也是基于观察者模式来实现,下面总结里面也会说到,观察者模式支持广播通信。有关BroadcastReceiver是怎么实现观察者模式的,有兴趣的朋友可以自己对比代码,和查看Android实现源码,自己动手才能加深印象。引入设计模式是为了对系统有更深入的理解。下面总结一下观察者模式的优缺点,方便我们在使用的时候,可以根据实际情况衡量。

A)优点

实现观察者和目标对象之间的抽象耦合。
观察者模式支持广播通信。被观察者会所有的登记过的观察者发出通知。
B)缺点

可能会引起多余的数据通知。
可能会导致通知数据循环,导致死锁产生。

0 0
原创粉丝点击