1、概述
有時被稱作發佈/訂閱模式,觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個目標對象。這個目標對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己
2、模式中的角色
- 抽象目標(Subject):它把所有觀察者對象的引用保存到一個聚集裏,每個目標都可以有任何數量的觀察者。抽象目標提供一個接口,可以增加和刪除觀察者對象。
- 具體目標(ConcreteSubject):將有關狀態存入具體觀察者對象;在具體目標內部狀態改變時,給所有登記過的觀察者發出通知。(可有可無,如果目標不聲明抽象或者接口)
- 抽象觀察者(Observer):爲所有的具體觀察者定義一個接口,在得到目標通知時更新自己。
- 具體觀察者(ConcreteObserver):實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與目標狀態協調。
3、結構圖
4、代碼實現
// 抽象目標類
abstract class Subject {
//定義一個觀察者集合用於存儲所有觀察者對象
protected ArrayList observers<Observer> = new ArrayList();
//註冊方法,用於向觀察者集合中增加一個觀察者
public void attach(Observer observer) {
observers.add(observer);
}
//註銷方法,用於在觀察者集合中刪除一個觀察者
public void detach(Observer observer) {
observers.remove(observer);
}
//聲明抽象通知方法
public abstract void notify();
}
// 具體目標類
class ConcreteSubject extends Subject {
//實現通知方法
public void notify() {
//遍歷觀察者集合,調用每一個觀察者的響應方法
for(Object obs:observers) {
((Observer)obs).update();
}
}
}
//抽象觀察者類,爲所有具體觀察者定義一個接口,在得到通知時更新自己
interface Observer {
//聲明響應方法
public void update();
}
//具體觀察者或具體通知者
class ConcreteAObserver implements Observer {
//實現響應方法
public void update() {
//具體響應代碼
}
}
class ConcreteBObserver implements Observer {
//實現響應方法
public void update() {
//具體響應代碼
}
}
具體調用:
// 實例化代理
Subject subjec = new ConcreteSubject ();
subjec.attach(new ConcreteAObserver());
subjec.attach(new ConcreteBObserver());
//通知更新
subjec.notify();
5、使用場景
- 當一個對象的改變需要給變其它對象時,而且它不知道具體有多少個對象有待改變時。
- 一個抽象某型有兩個方面,當其中一個方面依賴於另一個方面,這時用觀察者模式可以將這兩者封裝在獨立的對象中使它們各自獨立地改變和複用。
參考文章觀察者模式和設計模式學習筆記-觀察者模式。