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

  设计模式,对程序员来讲是一个坎,想在程序员这条路走得更远,设计模式是你的必修课。从大学时代接触GoF到工做几年后从新看设计模式,每次感受都不同。此次想借着分析Android Framework源码的机会,顺道整理一下设计模式的知识。html

  今天主要是先讲一下观察者模式,观察者模式对于作系统或者作公共库的朋友来讲,应该很熟悉,基本上全部系统都会用到这个模式。整理的时候,主要是对模式进行进步讲解而后结合Android里面应用进行说明。设计模式的说明主要是参考《研磨设计模式》这本书,这本书讲解了GoF里面23种模式,并且比GoF更容易理解。若是对设计模式不了解的朋友,能够看看《研磨设计模式》这本书。程序员

  结合Android源码的时候,主要是针对应用层的代码说明,并且尽可能使用简单例子代码,因此不会出现太多Android系统级的代码,大部分是咱们作APP开发时会编写的代码。设计模式

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

  (PS:新建的QQ群,有兴趣能够加入一块儿讨论:Android群:322599434)函数

 

一、观察者模式spa

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

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

 

 

 

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

 

二、观察者模式含义server

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

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

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

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

 

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

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

//Edited by mythou
//http://www.cnblogs.com/mythou/
   //目标对象接口
    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(); } } }

 

下面是观察者的实现:

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

 

应用中使用的代码:

 //Edited by mythou
//http://www.cnblogs.com/mythou/
  //客户端
    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!");
        }
    }

 

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

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

 A)控件中Listener监听方式

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

 

//Edited by mythou
//http://www.cnblogs.com/mythou/
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的定义,跟咱们前面定义一个观察者接口相似。

//Edited by mythou
//http://www.cnblogs.com/mythou/
  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模块位置变化,一般咱们会编写下面代码:

 

 
 
//Edited by mythou
//http://www.cnblogs.com/mythou/
// 经过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里面的具体实现。

 

五、结语

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

A)优势

  • 实现观察者和目标对象之间的抽象耦合。
  • 观察者模式支持广播通讯。被观察者会全部的登记过的观察者发出通知。

B)缺点

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

 

 

 

Edited by mythou

原创博文,转载请标明出处:http://www.cnblogs.com/mythou/p/3370340.html 

相关文章
相关标签/搜索