首先了解下观察者模式的概念;
观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态的时候,它的所有依赖者都会受到通知并自动更新;
上面的概念比较抽象,其实观察者模式也叫发布订阅模式,可以这样理解,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。
我们先来看看看Observable类的源码:
public class Observable {
private boolean changed = false;
//观察者集合
private Vector<Observer> 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;
}
//观察者数量
public synchronized int countObservers() {
return obs.size();
}
}
再来看看Observer接口的源码:
public interface Observer {
//更新观察者内容
void update(Observable o, Object arg);
}
下面了做个简单小测试。
定义目标类,继承Observable类:
public class MySubject extends Observable{
//目标需要通知观察者的内容
private String msg;
public void set(String s) {
this.msg=s;
//setChanged()将changed状态改为true
setChanged();
//在changed改为true后才能通知所有观察者
notifyObservers(msg);
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
定义观察者类,实现Observer接口:
public class ObjectA implements Observer {
private String msg;
@Override
public void update(Observable o, Object arg) {
//装换目标类并获取目标类需要通知的内容
msg=((MySubject)o).getMsg();
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
下面就开始测试,观察者可以是多个:
public class Test { public static void main(String[] args) { //创建目标对象 MySubject ms=new MySubject(); //创建观察者对象 ObjectA obj1=new ObjectA(); ObjectA obj2=new ObjectA(); ObjectA obj3=new ObjectA(); //addObserver(obj)是Suject类自带的添加观察者方法 ms.addObserver(obj1); ms.addObserver(obj2); ms.addObserver(obj3); ms.set("班长今晚请大家吃小龙虾"); System.out.println(obj1.getMsg()); System.out.println(obj2.getMsg()); System.out.println(obj3.getMsg()); } }
类似群发信息给三个朋友(obj1,obj2,obj3),今晚一起吃小龙虾,他们同时收到消息。测试结果如下:
班长今晚请吃小龙虾
班长今晚请吃小龙虾
班长今晚请吃小龙虾
观察者模式总结:
目标对象需要继承Observable,通过setChanged()和notifyObservers()通知观察者;
观察者需要实现Observer接口,通过.addObserver(this)来注册成为观察者,依靠update(Observable o, Object arg)来获取目标对象传递的数据。