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/ 这里面也有上面观察者模式的代码。