观察者模式在实际使用中是非常方便的,简单来说就是当一个数据源(即被观察者)的数据发生了变动,将自动通知到所有对应的观察者,此时观察者可以根据接收到的通知信息针对数据变动作出相应调整。
举个简单的在Android上的例子,我使用一个Service在后台进行时间倒计时,而我需要在多个Activity上同步显示该倒计时的信息。那么,Service上的倒计时功能即为被观察者(Observable),而这多个Activity则为观察者(Observer)。
Java自身带有Observable和Observer的接口,我们也可以自己自定义实现Observable和Observer,但是这就要求我们自己在Observable中维护Observer的列表。
首先,我们定义好观察者Observer的接口:
package com.vite.testobserver.observer.ifc;
/**
* 观察者接口
*
* @author trs
*
*/
public interface Observer {
void update(Object data);
}
然后定义被观察者Observable的接口:
package com.vite.testobserver.observer.ifc;
/**
* 被观察者接口
*
* @author trs
*
*/
public interface Observable {
/**
* 添加观察者
*
* @param observer
*/
public void addObserver(Observer observer);
/**
* 删除观察者
*
* @param observer
*/
public void deleteObserver(Observer observer);
/**
* 删除所有观察者
*/
public void deleteObservers();
/**
* 通知所有观察者
*
* @param data
*/
public void notifyObservers(Object data);
/**
* 通知所有观察者
*/
public void notifyObservers();
/**
* 获取观察者数量
*
* @return
*/
public int getCountObservers();
}
然后通过继承Observable的接口,自定义我们自己的被观察者类:
package com.vite.testobserver.observer;注意代码上面,记录观察者Observer的列表使用了static修饰,同时增加了两各静态方法 GlobalAddObserver和 GlobalDeleteObserver
import java.util.ArrayList;
import java.util.List;
import com.vite.testobserver.observer.ifc.Observable;
import com.vite.testobserver.observer.ifc.Observer;
/**
* 自定义被观察者
*
* @author trs
*
*/
public class TimeCountObservable implements Observable {
private static List<Observer> observerList = new ArrayList<Observer>();
public static void GlobalAddObserver(Observer observer) {
if (observerList == null)
throw new NullPointerException();
if (observer == null)
throw new NullPointerException();
synchronized (observerList) {
if (!observerList.contains(observer))
observerList.add(observer);
}
}
public static void GlobalDeleteObserver(Observer observer) {
if (observerList == null)
throw new NullPointerException();
if (observer == null)
throw new NullPointerException();
synchronized (observerList) {
if (observerList.contains(observer))
observerList.remove(observer);
}
}
@Override
public synchronized void addObserver(Observer observer) {
// TODO Auto-generated method stub
if (observerList == null)
throw new NullPointerException();
if (observer == null)
throw new NullPointerException();
synchronized (observerList) {
if (!observerList.contains(observer))
observerList.add(observer);
}
}
@Override
public synchronized void deleteObserver(Observer observer) {
// TODO Auto-generated method stub
if (observerList == null)
throw new NullPointerException();
if (observer == null)
throw new NullPointerException();
synchronized (observerList) {
if (observerList.contains(observer))
observerList.remove(observer);
}
}
@Override
public synchronized void deleteObservers() {
// TODO Auto-generated method stub
if (observerList == null)
throw new NullPointerException();
synchronized (observerList) {
observerList.removeAll(observerList);
}
}
@Override
public void notifyObservers(Object data) {
// TODO Auto-generated method stub
if (observerList == null)
throw new NullPointerException();
synchronized (observerList) {
for (Observer observer : observerList) {
observer.update(data);
}
}
}
@Override
public void notifyObservers() {
// TODO Auto-generated method stub
notifyObservers(null);
}
@Override
public int getCountObservers() {
// TODO Auto-generated method stub
if (observerList == null)
throw new NullPointerException();
synchronized (observerList) {
return observerList.size();
}
}
}
这是为了在Service以外的地方动态添加和删除观察者,写得比较简单粗暴,在实际应用过程中我们也可以根据需求进行不同的自定义。
然后,通过对Activity实现观察者Observer接口中的updata方法,并将自身通过GlobalAddObserver加入到观察者列表中。
这样,在后台Service里的倒计时功能中调用notifyObservers方法,通知所有在观察者列表中的观察者,并将数据传递到updata方法中,就完成了一次数据更新。
private class TimeCountDownTimer extends CountDownTimer {
public TimeCountDownTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
// TODO Auto-generated constructor stub
}
@Override
public void onFinish() {
// TODO Auto-generated method stub
timeCountObservable.notifyObservers("00:00");
if (timer != null)
timer.cancel();
timer = null;
}
@Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
Date date = new Date(millisUntilFinished);
timeCountObservable.notifyObservers(df.format(date));
}
}
通过实现Observer接口,我们自定义一个可以异步处理的TimeCountObserver:
package com.vite.testobserver.observer;
import android.os.Handler;
import com.vite.testobserver.observer.ifc.Observer;
public abstract class TimeCountObserver implements Observer {
private Handler handler;
private Object object;
public TimeCountObserver(Handler handler) {
this.handler = handler;
}
public abstract void onUpdate(Object data);
@Override
public void update(Object data) {
// TODO Auto-generated method stub
object = data;
if (handler == null)
onUpdate(object);
else
handler.post(new LocalRunnable());
}
private class LocalRunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
onUpdate(object);
}
}
}
然后在Activity中就无需实现Observer接口,而是实例化TimeCountObserver,并且通过 onUpdate方法更新数据:
timeCountObserver = new TimeCountObserver(new Handler()) {
@Override
public void onUpdate(Object data) {
// TODO Auto-generated method stub
content.setText(data.toString());
}
};
TimeCountObservable.GlobalAddObserver(timeCountObserver);
效果如下图所示:
该例子的下载地址如下: