觀察者模式定義一對多依賴:主題 (Subject) 狀態變更時,自動通知所有觀察者 (Observer) 更新。別名:發布-訂閱、Model/View、Source/Listener、Dependents。
attach()/detach()/notifyObservers()。update() 介面。notifyObservers()。update() 同步狀態。// Subject 介面
public interface Subject {
void attach(Observer o);
void detach(Observer o);
void notifyObservers();
}
// ConcreteSubject 使用 Vector 管理觀察者
public class ConcreteSubject implements Subject {
private Vector obs = new Vector<>();
public void attach(Observer o) { obs.add(o); }
public void detach(Observer o) { obs.remove(o); }
public void notifyObservers() {
for (Observer o : obs) o.update();
}
}
// Observer 介面
public interface Observer { void update(); }
// ConcreteObserver
public class ConcreteObserver implements Observer {
public void update() { /* 同步邏輯 */ }
}
package java.util;
public interface Observer {
void update(Observable o, Object arg); // arg 可攜帶變更細節
}
addObserver(Observer) / deleteObserver(Observer):註冊/移除。setChanged():標記狀態已變更 (內部 changed flag)。notifyObservers() / notifyObservers(Object arg):若 changed==true,複製觀察者陣列並逐一呼叫 update(this, arg),最後 clearChanged()。hasChanged()、countObservers()、deleteObservers()。public class Watched extends Observable {
private String data;
public void changeData(String d) {
if (!data.equals(d)) { data = d; setChanged(); notifyObservers(); }
}
public String retrieveData() { return data; }
}
public class Watcher implements Observer {
public Watcher(Watched w) { w.addObserver(this); }
public void update(Observable o, Object arg) {
System.out.println("Data changed to: " + ((Watched)o).retrieveData());
}
}
// Client
Watched w = new Watched();
Observer watcher = new Watcher(w);
w.changeData("A"); // 通知
w.changeData("A"); // 未變更,不通知
w.changeData("B"); // 通知
輸出:
Data changed to: A
Data changed to: B
菩薩 (Observable) 將淨瓶拋入海中 → notifyObservers();守瓶龜 (Observer) 感知並駕瓶歸岸 → update()。生動詮釋「發布-訂閱」鬆耦合關係。
| 技術領域 | 事件源 (Publisher) | 事件監聽器 (Subscriber) | 註冊方法 |
|---|---|---|---|
| AWT/Swing (DEM) | Component (Button 等) | ActionListener, MouseListener 等 | addActionListener() |
| Servlet | ServletContext, HttpSession | ServletContextListener, HttpSessionAttributeListener | @WebListener 或 web.xml |
| SAX2 XML 解析 | XMLReader | ContentHandler, ErrorHandler | setContentHandler() |