Java Observer接口和Observable类实现观察者模式

时间:2021-11-09 18:13:32

对于观察者模式,其实Java已经为我们提供了已有的接口和类。对于订阅者(Subscribe,观察者)Java为我们提供了一个接口,JDK源码如下:

 package java.util;

 public interface Observer {
void update(Observable o, Object arg);
}

上述仅提供一个update方法用于接收通知者的通知做出相应改变。

Java还为我们提供了一个通知者(Publish,发布者),JDK源码如下:

 package java.util;

 public class Observable {
private boolean changed = false;  //是否改变状态
private Vector obs;    //Vector利用同步方法来线程安全,线程安全在多线程情况下不会造成数据混乱 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();  //将Vector转换成数组
clearChanged();    //重置状态
} for (int i = arrLocal.length-; i>=; 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();
}
}

首先,使用Vector,Vector相比于ArrayList来说,它是线程安全的。其次,在添加和删除观察者时对两个方法使用了synchronized关键字,这都是在为多线程考虑。确实Java源码并不是那么可怕,它同样也是由一些最简单最基础的组合而来。

接下来看看是如何利用Java提供的接口和方法来实现观察者模式。

Observable:

 public class Publish extends Observable {

     private String data = "";

     public String getData() {
return data;
} public void setData(String data) {
if (!this.data.equals(data)) {
this.data = data;
setChanged(); //改变通知者的状态
}
notifyObservers(); //调用父类Observable方法,通知所有观察者
}
}
Observer:
 public class Subscribe implements Observer {

     public Subscribe(Observable o) {
//将该观察者放入待通知观察者里
o.addObserver(this);
} @Override
public void update(Observable o, Object arg) {
System.out.println("收到了消息:" + ((Publish)o).getData());
}
}

测试:

 public class ObserverTest {

     public static void main(String[] args) {
Publish publish = new Publish();
Subscribe subscribe = new Subscribe(publish);
publish.setData("发布一个消息");
}
}

运行结果:

收到了消息:发布一个消息

这样就利用了Java给我们提供的Observer接口和Observable类实现了观察者模式。