概述
- 主題接口:被觀察的對象,接口定義了新增觀察者、刪除觀察者和通知觀察者等方法(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();
}
}