文章目錄
- 定義
- 結構
- Demo | 代碼
- Subject目標類
- Observer抽象觀察者
- 觀察者1 | CPU監聽器
- 觀察者2 | 內存監聽器
- 客戶端 | Client
- 優點
- 適合場景
定義
所謂觀察者模式就是你是被觀察的那個對象,你爸爸媽媽就是觀察者,一天24h盯著你,一旦你不聽話,他們要你聽話,你的狀態發生變化以后,他們接收到你的狀態發生了改變。
結構
如下圖,服務器就作為被觀察者,三個傳感器就是觀察者。這是一種抽象的表達方式!
- Subject被觀察的目標
- Observer觀察者抽象類
- 具體觀察者實現類
- Client客戶端
Demo | 代碼
Subject目標類
我們需要一個Subject目標類,內部含有觀察者對象的集合,在必要的時候觸發事件。
- Subject被觀察的目標
- Observer觀察者抽象類
- 具體觀察者實現類
- Client客戶端
/*** 這個Server類就是服務類,作為Subject,別觀察的目標!* @author linghu* @date 2024/7/4 11:50*/
public class Server {private List<Observer> observers= new ArrayList<Observer>();private int cpu;private int memory;public Server() {}//變更服務器狀態public void changeState(int cpu,int memory){this.cpu=cpu;this.memory=memory;System.out.println("CPU:" + cpu + "%,內存占用:" + memory + "%");//通知所有觀察者對象,使它們能夠自動更新自己notifyAllObservers();}public Server(int cpu, int memory) {this.cpu = cpu;this.memory = memory;}public int getCpu() {return cpu;}public void setCpu(int cpu) {this.cpu = cpu;}public int getMemory() {return memory;}public void setMemory(int memory) {this.memory = memory;}public void addObserver(Observer observer){observers.add(observer);}public void notifyAllObservers(){for (Observer observer :observers) {observer.update();}}}
Observer抽象觀察者
這個抽象主要是封裝了目標對象和觀察者要做的事情。
/*** @author linghu* @date 2024/7/4 12:02*/
public abstract class Observer {protected Server subject;//服務類,目標對象public abstract void update();//觀察者要做的事情
}
觀察者1 | CPU監聽器
/*** @author linghu* @date 2024/7/4 12:04* CPU監聽器*/
public class CpuObserver extends Observer{//傳入目標類subjectpublic CpuObserver(Server subject) {//初始化的時候完成數據雙向綁定工作this.subject=subject;this.subject.addObserver(this);}@Overridepublic void update() {//監聽CPU的運行狀況,負載超過80%就發出警報if(subject.getCpu() >= 80){System.out.println("警報:CPU當前" + subject.getCpu()+ "%即將滿載,請 速查明原因");}}
}
觀察者2 | 內存監聽器
/*** @author linghu* @date 2024/7/4 12:46* 內存監聽器*/
public class MemoryObserver extends Observer{public MemoryObserver(Server subject) {this.subject=subject;this.subject.addObserver(this);}@Overridepublic void update() {if(subject.getMemory() >= 80){System.out.println("警報:服務器內存已經占用超過" + subject.getMemory()+ "%即將滿載,請 速查明原因");}}
}
客戶端 | Client
/*** 觀察者模式:讓多個觀察者對象同時監聽某一個主題對象。* 這個主題對象在狀態發生變化時,會通知所有觀察者對象,* 使它們能夠自動更新自己。* @author linghu* @date 2024/7/4 12:49* 客戶端*/
public class Client {public static void main(String[] args) throws InterruptedException {Server subject = new Server();//完成兩個觀察者和一個目標類的綁定//引入新的觀察者,這里可以利用反射,動態加載~new CpuObserver(subject);new MemoryObserver(subject);//==============================while (true){int cpu=new Random().nextInt(100);int memory=new Random().nextInt(100);//調用具體的業務~subject.changeState(cpu,memory);Thread.sleep(5000);//5s}}
}
優點
-
開閉原則。 你?需修改發布者代碼就能引?新的訂閱者類 (如果是發布者接?則可輕松引?發布者類)。
-
你可以在運?時建?對象之間的聯系。
適合場景
- 所有的發布訂閱模式
- 構建事件監聽機制,比如按下觸發click事件