一、模式介紹
觀察者模式(又被稱爲發佈-訂閱(Publish/Subscribe)模式,屬於行爲型模式的一種,它定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態變化時,會通知所有的觀察者對象,使他們能夠自動更新自己。
二、模式結構
三、模式代碼
1、抽象觀察者
package com.example.demo.observer;
//抽象觀察者
public abstract class Observer {
public abstract void update(String msg);
}
2、 主題(被觀察者)
package com.example.demo.observer;
import java.util.ArrayList;
import java.util.List;
//主題
public class Subject {
private List<Observer> observers = new ArrayList<>(); //狀態改變
public void setMsg(String msg) {
notifyAll(msg);
}
//訂閱(註冊)
public void addAttach(Observer observer) {
observers.add(observer);
}
//通知所有訂閱(註冊)的觀察者
private void notifyAll(String msg) {
for (Observer observer : observers) {
observer.update(msg);
}
}
}
3、觀察者A
package com.example.demo.observer;
//A觀察者
public class A_Student extends Observer {
public void update(String msg) {
System.out.println("A同學:"+msg+" "+"快看書!");
}
}
4、觀察者B
package com.example.demo.observer;
//B觀察者
public class B_Student extends Observer {
public void update(String msg) {
System.out.println("B同學:"+msg+" "+"手機收起來!");
}
}
5、觀察者C
package com.example.demo.observer;
//C觀察者
public class C_Student extends Observer {
public void update(String msg) {
System.out.println("C同學:"+msg+" "+"哎呀,書拿反了!");
}
}
6、模擬主題改變觀察者狀態
package com.example.demo.observer;
public class Main {
public static void main(String[] args) {
Subject subject = new Subject();
subject.addAttach(new A_Student());
subject.addAttach(new B_Student());
subject.addAttach(new C_Student());
subject.setMsg("老師來了!");
}
}
7、結果
四、使用情景
1、對一個對象狀態的更新,需要其他對象同步更新,而且其他對象的數量動態可變。
2、對象僅需要將自己的更新通知給其他對象而不需要知道其他對象的細節。
3、事件多級觸發場景。
4、跨系統的消息交換場景,如消息隊列、事件總線的處理機制。
五、優缺點
優點:
解除耦合,讓耦合的雙方都依賴於抽象,從而使得各自的變換都不會影響另一邊的變換。
缺點:
在應用觀察者模式時需要考慮一下開發效率和運行效率的問題,程序中包括一個被觀察者、多個觀察者,開發、調試等內容會比較複雜,而且在Java中消息的通知一般是順序執行,那麼一個觀察者卡頓,會影響整體的執行效率,在這種情況下,一般會採用異步實現。
六、demo地址
https://github.com/tongyuxin1/designModel/tree/master/src/main/java/com/example/demo