概述
- 主题接口:被观察的对象,接口定义了新增观察者、删除观察者和通知观察者等方法(ISubject)。
- 具体主题:实现主题接口中的方法。当其状态改变时,它将会通过这个变化通知观察者(ConcreteSubject)。
- 观察者接口:定义了观察者的基本方法。当依赖状态改变时,主题接口会调用观察者的update方法(IObserver)。
- 具体观察者:实现观察者接口的update方法(ConcreteObserver)。
代码示例
package observer;
public interface Isubject{
// 添加观察者
public void attach(IObserver observer);
// 删除观察者
public void detach(IObserver observer);
// 通知观察者
pubic void inform();
}
观察者接口:package observer;
public interface IObserver{
// 更新观察者
public void update(Event event);
}
具体主题:package observer;
pubic class ConcreteSubject implements ISubject {
List<IObserver> observers = new ArrayList<>();
public void attach(IObserver observer){
observers.add(observer);
}
public void detach(IObserver observer){
observers.remove(observer);
}
public void inform(){
Event event = new Event();
for(IObserver observer : observers){
observer.update(event);
}
}
}
具体观察者:<span style="font-size:14px;">package observer;
public class ConcreteObserver implements IObserver{
public void update(Event event){
System.out.println("Received information.");
}
}</span>
JDK内置的观察者JDK中已经实现了一套观察者模式。在java.util包中,包括java.util.Observable类和java.util.Observer接口,它们的关系接口图如下:
package java.util;
public class Observable {
private boolean changed = false;
private Vector 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();
}
}