MrDuoduo 2015-10-25
my git : https://github.com/hejiawang/
一、观察者设计模式定义:
定义对象之间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
以上是文言文的,用普通话说就是,有几个对象去观察一个对象的状态,这一个对象状态发生改变时,会通知观察它的那几个对象,这几个对象观察到被观察对象状态发生变化了,然后自己就会做一些事情。这里有两类对象,一个是观察者,一个是被观察者,当然在JDK中,已经为我们准备好了观察者模式的这两类对象,我们先看看用UML体现自己定义的观察者模式如下:
二、自己定义的观察者模式的代码:
首先要有被观察者:
package com.wang.observerPattern; import java.util.Vector; /** * 被观察者 * * @author wang * */ public abstract class Subject { /** * 定义一个观察者数组 */ private Vector<Observer> obsVector = new Vector<Observer>(); /** * 增加一个观察者 * * @param o * 观察者 */ public void addObserver(Observer o) { this.obsVector.add(o); } /** * 删除一个观察者 * * @param o * 观察者 */ public void delObserver(Observer o) { this.obsVector.remove(o); } /** * 通知所有观察者 */ public void notifyObserver() { for (Observer o : this.obsVector) { o.update(); } } }
具体被观察者:
package com.wang.observerPattern; /** * 具体被监视者 * * @author wang * */ public class ConcreteSubject extends Subject { /** * 被监视者的具体业务 */ public void doSomething() { System.out.println(" subject doSomething ... "); // 通知观察者 super.notifyObserver(); } }
观察者:
package com.wang.observerPattern; /** * 观察者 * * @author wang * */ public interface Observer { /** * 更新方法 */ public void update(); }
具体的观察者:
package com.wang.observerPattern; /** * 具体观察者 * * @author wang * */ public class ConcreteObject implements Observer { @Override public void update() { System.out.println("ConcreteObject update ... "); } }
自己定义的观察者模式的应用:
package com.wang.observerPattern; public class App { public static void main(String[] args) { ConcreteSubject subject = new ConcreteSubject(); Observer obs = new ConcreteObject(); subject.addObserver(obs); subject.doSomething(); } }
这样,就自己定义了一个观察者模式。观察者模式有利于观察者和被观察者之间的抽象耦合,能够建立一套触发机制
三、上面说过,JDK已经为我么定义了观察者和被观察者的接口,以方便哪些暴漏狂们使用,我们通过继承或者实现,就能很方便的完成观察者模式。JDK中提供的java.util.Observable实现类和java.util.Observer接口。
修改过的被观察者:
package com.wang.observerPattern.jdk; import java.util.Observable; public class Subject extends Observable implements ISubject{ //这里的ISubject,是自己定义的背观察者接口,定义这个被观察者都要完成什么业务逻辑 public void doSomething(){ system.out.println("xxx"); super.setChanged(); super.notifyObservers("yyy"); } }
观察者的代码:
package com.wang.observerPattern.jdk; import java.util.Observable; import java.util.Observer; public class MyObserverimplements Observer { @Override public void update(Observable o, Object arg) { System.out.println(arg.toString()); } }
App应用类与上面的一样,我们能够看到,有了JDK自带的观察者定义,我们在使用观察者模式,确实方便了很多,在使用时不要忘了在被观察者中,通知观察者的代码:
super.setChanged(); super.notifyObservers("yyy");
四、观察者模式在Android开发中的应用。
在Android开发中,观察者模式是非常常用的,能够实现触发机制,Android源码也为我们提供了观察者的使用方法,比如说在四大主件中的内容提供者ContentProvider中。首先定义一个Uri,然后在被观察者的方法中使用代码:
getContext().getContentResolver().notifyChange(uri, null);
在观察者中注册,使用代码:
this.getContentResolver().registerContentObserver(uri, true, new MyObserver()); //MyObserver是一个内部类 private class MyObserver extends ContentObserver { public MyObserver() { super(new Handler()); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); System.out.println("观察到修改操作"); } }
举一个示例。比如说,我想在手机产生呼叫记录时进行一些操作,那么,就可以观察手机呼叫记录数据的变化,就能够用观察者模式实现,
private class InnerTeleStateListener extends PhoneStateListener { /** * 当电话呼叫状态发生改变时调用的方法 */ @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state) { case TelephonyManager.CALL_STATE_RINGING: // 响铃状态 getContentResolver().registerContentObserver( CallLog.Calls.CONTENT_URI, true, new MyObserver(new Handler(), incomingNumber)); } break; } super.onCallStateChanged(state, incomingNumber); } }
上面的代码就是说,当手机来电话后,我们就观察通话记录是否发生变化,只要数据一变化,就执行MyObserver类中的onChange方法
private class MyObserver extends ContentObserver { private String incomingNumber; public MyObserver(Handler handler, String incomingNumber) { super(handler); this.incomingNumber = incomingNumber; } // 当内容发生变化时调用 @Override public void onChange(boolean selfChange) { super.onChange(selfChange); System.out.println("观察到数据变化"); // 取消内容观察者 getContentResolver().unregisterContentObserver(this); } }
大功告成。。。观察者模式还是很好理解的,也是很常用的。
附上Android中ContentProvider观察者模式的测试的工程,AndroidProject,更多更全的代码欢迎前去我的git代码库:https://github.com/hejiawang/ 这里面也有上面观察者模式的代码。