观察者模式--Java设计模式
2015-06-13 11:23
459 查看
观察者模式定义:定义了对象之间的一对多的依赖,这样一来,当一个对象发生改变状态的时候,它的所有依赖者都会收到通知并自动更新。参考如下图:
观察者设计模式也叫发布-订阅模式。
也可以称作:出版者+订阅者 = 观察者模式
在Android中观察者模式的实例有:广播机制,ContentObserver的注册方式,一个是同步的观察者模式,一个是异步的观察者模式。
当两个对象之间松耦合,它们依然可以交互,但是不清楚彼此的细节,观察者提供了一种对象的设计,可以降低之间的耦合,避免对象的双向依赖。
举例:在Android中很多的Listener是观察者模式,比如点击事件的OnClickListener,就是为了避免对象的双向依赖。
Java源码中上述代码中用的是推模式,当然源码中也有拉模式,即主动查询的模式。拉模式就像广播一样,通过onReceive()方法拉起来一些动作的,还有像ContentObserver可以通过拉模式,当数据库发生改变的时候,通过onChange()方法来调用一些操作。
总结:通过Handler来实现异步的观察者模式,即构造Observer对象的时候传一个Handler的对象,这样在回调的时候,就用handler来发送异步的消息在主线程上来执行相应的操作。
观察者设计模式也叫发布-订阅模式。
也可以称作:出版者+订阅者 = 观察者模式
在Android中观察者模式的实例有:广播机制,ContentObserver的注册方式,一个是同步的观察者模式,一个是异步的观察者模式。
当两个对象之间松耦合,它们依然可以交互,但是不清楚彼此的细节,观察者提供了一种对象的设计,可以降低之间的耦合,避免对象的双向依赖。
举例:在Android中很多的Listener是观察者模式,比如点击事件的OnClickListener,就是为了避免对象的双向依赖。
—-先来看看Java源码中的观察者模式:
Observer观察者接口:
package com.daming.java.observer; public interface Observer { void update(Observable observable, Object arg); }
对象Observable 类的实现
package com.daming.java.observer; import java.util.Vector; public class Observable { private boolean changed = false; private Vector obs; public Observable() { obs = new Vector(); } public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length - 1; i >= 0; i--) ((Observer) arrLocal[i]).update(this, arg); } public synchronized void deleteObservers() { obs.removeAllElements(); } protected synchronized void setChanged() { changed = true; } protected synchronized void clearChanged() { changed = false; } public synchronized boolean hasChanged() { return changed; } /** * Returns the number of observers of this <tt>Observable</tt> object. * * @return the number of observers of this object. */ public synchronized int countObservers() { return obs.size(); } }
MyObserver 观察者对象的实现
package com.daming.java.observer; public class MyObserver implements Observer{ @Override public void update(Observable observable, Object arg) { System.out.println("observable :" + observable + "arg :" + arg); } }
MyObserver2 观察者对象的实现
package com.daming.java.observer; public class MyObserver2 implements Observer{ @Override public void update(Observable observable, Object arg) { System.out.println("observable2 :" + observable + "arg2 :" + arg); } }
TestObserver类的实现
package com.daming.java.observer; public class TestObserver { /** * @param args */ public static void main(String[] args) { Observable observable = new Observable(); MyObserver myObserver = new MyObserver(); MyObserver2 myObserver2 = new MyObserver2(); observable.addObserver(myObserver); observable.addObserver(myObserver2); observable.setChanged(); observable.notifyObservers(14); observable.setChanged(); observable.notifyObservers("I am daming"); } }
Log输入结果:
observable2 :com.daming.java.observer.Observable@14318bbarg2 :14 observable :com.daming.java.observer.Observable@14318bbarg :14 observable2 :com.daming.java.observer.Observable@14318bbarg2 :I am daming observable :com.daming.java.observer.Observable@14318bbarg :I am daming
Java源码中上述代码中用的是推模式,当然源码中也有拉模式,即主动查询的模式。拉模式就像广播一样,通过onReceive()方法拉起来一些动作的,还有像ContentObserver可以通过拉模式,当数据库发生改变的时候,通过onChange()方法来调用一些操作。
—-接着我们来看看Android中异步的观察者模式。
ContentObserver就是异步的观察者模式,异步的观察者有什么好处呢?不阻塞观察者的回调。在同步通知中会有阻塞问题,各个Observer的响应方法是串行的,如果有一个observer耗时的话就会阻塞其他observer接收者了,这样就有可能就会引起bug来,所以在设计的时候多考虑一些,是否考虑用异步的观察者模式,让并发处理快一些;我们通过一个简单的demo来学习下异步的观察者模式:先来看看Observer,这个Android中是抽象的类
package cn.daming.observer.design; import android.os.Handler; import android.util.Log; public abstract class Observer { private Handler mHandler; public Observer(Handler handler) { mHandler = handler; } public void onChange() { } public final void dispatchChange() { Log.v("daming", "Observer dispatchChange is mHandler== null :" + (mHandler == null)); if (mHandler == null) { onChange(); } else { mHandler.post(new NotificationRunnable()); } } private final class NotificationRunnable implements Runnable { @Override public void run() { Log.v("daming", "NotificationRunnable dispatchChange is run ... "); Observer.this.onChange(); } } }
接着来看看ObserverService这个类的实现:
package cn.daming.observer.design; import java.util.ArrayList; import java.util.List; import android.util.Log; public class ObserverService { private int mState; private List<Observer> mObservers = new ArrayList<Observer>(); public final void registerObserver(Observer observer) { if (!mObservers.contains(observer)) { mObservers.add(observer); } } public final void unregisterObserver(Observer observer) { Log.v("daming", "ObserverService unregisterObserver :"); mObservers.remove(observer); } public void notifyChange() { for (Observer observer : mObservers) { observer.dispatchChange(); } } public int getState() { return mState; } public void setState(int state) { mState = state; notifyChange(); } }
最后我们来写测试类FirstActivity :
package cn.daming.observer.design; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import com.daming.designtraning.R; public class FirstActivity extends Activity { private ObserverService mObserverService; private Button mButton; private int mState = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButton = (Button) findViewById(R.id.button); mObserverService = new ObserverService(); mObserverService.registerObserver(mFirstObserver); mObserverService.setState(++mState); mButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mObserverService.setState(++mState); } }); } @Override protected void onDestroy() { super.onDestroy(); mObserverService.unregisterObserver(mFirstObserver); } @Override protected void onResume() { super.onResume(); } @Override protected void onStop() { super.onStop(); } private Observer mFirstObserver = new Observer(new Handler()) { @Override public void onChange() { int state = mObserverService.getState(); Log.v("daming", "FirstObserver onChange is run state :" + state); } }; }
总结:通过Handler来实现异步的观察者模式,即构造Observer对象的时候传一个Handler的对象,这样在回调的时候,就用handler来发送异步的消息在主线程上来执行相应的操作。
相关文章推荐
- 项目中使用的spring 注解说明
- 使用Java完成《算法导论》习题2.3-5
- Java中&和&&的区别和联系
- 语料处理中连字符的处理
- Box2d碰撞粘滞的问题(java)
- 使用Java完成《算法导论》习题2.3-4
- how to do graphics in java(quote from big java, 5e)?
- Java-核心技术总结-第3章
- eclipse打开文件所在的本地文件夹
- 初识Struts2框架
- Java 工厂模式
- Java解惑之try catch finally
- 使用Java完成《算法导论》习题2.3-2
- 详细介绍Java中的堆、栈和常量池
- 【Hadoop】1、Hadoop开山篇之虚拟机下ubuntu安装jdk1.7
- Java循环中标签的使用
- Java String split方法的正则表达式输入
- java JAXB + STAX(是一种针对XML的流式拉分析API)读取xml
- Java基本数据类型总结
- 解决eclipse中logcat不显示log的问题