定義
定義對象之間的一種一對多依賴關係,使得每當一個對象狀態發生改變時,其相關依賴對象皆得到通知並被自動更新。觀察者模式的別名包括髮布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。觀察者模式是一種對象行爲型模式。
UML類圖
代碼實現
Observer.java
public abstract class Observer {
public abstract void update();
}
Subject.java
public abstract class Subject {
protected ArrayList<Observer> list = new ArrayList<>();
public void attach(Observer obs) {
list.add(obs);
}
public void detach(Observer obs) {
list.remove(obs);
}
public abstract void notifyObserver();
}
ConcreteObserver.java
public class ConcreteObserver extends Observer {
private String type;
public ConcreteObserver(String type) {
this.type = type;
}
@Override
public void update() {
System.out.println("update:"+type);
}
}
ConcreteSubject.java
public class ConcreteSubject extends Subject {
@Override
public void notifyObserver() {
for (Observer obs:list) {
obs.update();
}
}
}
Main.java
Observer observerA = new ConcreteObserver("A");
Observer observerB = new ConcreteObserver("B");
Observer observerC = new ConcreteObserver("C");
ConcreteSubject subject = new ConcreteSubject();
subject.attach(observerA);
subject.attach(observerB);
subject.attach(observerC);
subject.notifyObserver();
打印結果:
update:A
update:B
update:C
優缺點
主要優點
-
觀察者模式可以實現表示層和數據邏輯層的分離,定義了穩定的消息更新傳遞機制,並抽象了更新接口,使得可以有各種各樣不同的表示層充當具體觀察者角色。
-
觀察者模式在觀察目標和觀察者之間建立一個抽象的耦合。觀察目標只需要維持一個抽象觀察者的集合,無須瞭解其具體觀察者。由於觀察目標和觀察者沒有緊密地耦合在一起,因此它們可以屬於不同的抽象化層次。
-
觀察者模式支持廣播通信,觀察目標會向所有已註冊的觀察者對象發送通知,簡化了一對多系統設計的難度。
-
觀察者模式滿足“開閉原則”的要求,增加新的具體觀察者無須修改原有系統代碼,在具體觀察者與觀察目標之間不存在關聯關係的情況下,增加新的觀察目標也很方便。
主要缺點
-
如果一個觀察目標對象有很多直接和間接觀察者,將所有的觀察者都通知到會花費很多時間。
-
如果在觀察者和觀察目標之間存在循環依賴,觀察目標會觸發它們之間進行循環調用,可能導致系統崩潰。
-
觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化。