可進入我的部落格檢視原文。
定義
觀察者模式定義了物件之間的一對多依賴,使得當一個物件改變狀態時,它的所有依賴者都會收到通知並自動更新。觀察者模式又叫釋出/訂閱模式。
角色
抽象主題(Subject):它把所有觀察者物件的引用儲存到一個列表裡,每個主題都可以有任何數量的觀察者。抽象主題提供一個介面,可以增加和刪除觀察者物件。
具體主題(ConcreteSubject):將有關狀態存入具體觀察者物件;在具體主題內部狀態改變時,給所有登記過的觀察者發出通知。
抽象觀察者(Observer):為所有的具體觀察者定義一個介面,在得到主題通知時更新自己。
具體觀察者(ConcreteObserver):實現抽象觀察者角色所要求的更新介面,以便使本身的狀態與主題狀態協調。
類圖
示例
以獵頭-求職者為例。獵頭是主題,求職者是觀察者。
Subject 介面
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyAllObservers();
}複製程式碼
Observer 介面
public interface Observer {
public void update(Subject s);
}複製程式碼
HeadHunter 類實現 Subject 介面
import java.util.LinkedList;
public class HeadHunter implements Subject {
private LinkedList<Observer> userList;
private LinkedList<String> jobs;
public HeadHunter() {
userList = new LinkedList<Observer>();
jobs = new LinkedList<String>();
}
@Override
public void registerObserver(Observer o) {
userList.add(o);
}
@Override
public void removeObserver(Observer o) {
userList.remove(o);
}
@Override
public void notifyAllObservers() {
for (Observer o: userList) {
o.update(this);
}
}
public void addJob(String job) {
jobs.add(job);
notifyAllObservers();
}
public LinkedList<String> getJobs() {
return jobs;
}
public String toString() {
return jobs.toString();
}
}複製程式碼
JobSeeker 類實現 Observer 介面
public class JobSeeker implements Observer {
private String name;
public JobSeeker(String name) {
this.name = name;
}
@Override
public void update(Subject s) {
System.out.println(this.name + " got notified!");
System.out.println(s);
}
}複製程式碼
測試
public class Main {
public static void main(String[] args) {
HeadHunter hh = new HeadHunter();
JobSeeker lbd = new JobSeeker("lbd");
JobSeeker lbx = new JobSeeker("lbx");
JobSeeker lbn = new JobSeeker("lbn");
JobSeeker lbb = new JobSeeker("lbb");
hh.registerObserver(lbd);
hh.registerObserver(lbx);
hh.registerObserver(lbn);
hh.registerObserver(lbb);
hh.removeObserver(lbb);
hh.addJob("looking for Java engineers");
hh.addJob("looking for Python engineers");
}
}複製程式碼
輸出
lbd got notified!
[looking for Java engineers]
lbx got notified!
[looking for Java engineers]
lbn got notified!
[looking for Java engineers]
lbd got notified!
[looking for Java engineers, looking for Python engineers]
lbx got notified!
[looking for Java engineers, looking for Python engineers]
lbn got notified!
[looking for Java engineers, looking for Python engineers]複製程式碼
總結
觀察者模式使主題和觀察者之間鬆耦合,鬆耦合的設計能夠讓我們建立有彈性的OO系統,能夠應對變化,因為物件直接的相互依賴降到了最低。
其他
- 上面的例子是觀察者模式的“推”模式,還有一種“拉”模式。
- Java 的 java.util 庫裡面,提供了一個 Observable 類以及一個 Observer 介面,構成 Java 語言對觀察者模式的支援。
可進入我的部落格檢視原文。