什麼是觀察者 觀察者模式的主要角色包括: 主題(Subject): 也稱為被觀察者或可觀察對象。它維護了一系列觀察者對象,並提供方法用於註冊、刪除和通知觀察者。當主題的狀態發生改變時,它會通知所有註冊的觀察者。 觀察者(Observer): 觀察主題的對象。觀察者定義了一個更新方法,主題在狀態改變時 ...
什麼是觀察者
觀察者模式的主要角色包括:
-
主題(Subject): 也稱為被觀察者或可觀察對象。它維護了一系列觀察者對象,並提供方法用於註冊、刪除和通知觀察者。當主題的狀態發生改變時,它會通知所有註冊的觀察者。
-
觀察者(Observer): 觀察主題的對象。觀察者定義了一個更新方法,主題在狀態改變時會調用這個方法來通知觀察者。觀察者可以根據主題的通知來執行相應的操作。
觀察者的應用
觀察者模式在實際應用中經常用於處理事件驅動的編程場景,如圖形用戶界面(GUI)開發、消息傳遞系統等。通過觀察者模式,可以實現對象之間的解耦,提高系統的靈活性和可維護性。
在Spring Framework
中,觀察者模式的應用非常廣泛,尤其在Spring的事件驅動機制中。Spring的事件機制允許對象在特定事件發生時發佈事件,並允許其他對象註冊為監聽器以接收這些事件。這與觀察者模式的概念非常相似,其中事件源就是觀察者模式中的主題,而事件監聽器就是觀察者。
應用程式事件: Spring允許應用程式發佈自定義事件,並提供了ApplicationEvent和ApplicationListener介面。應用程式可以創建自定義事件類,併在需要時發佈這些事件。其他對象可以實現ApplicationListener介面並註冊為監聽器,以接收並處理這些事件。
Spring MVC事件: 在Spring MVC中,可以使用 ApplicationEventPublisher
介面發佈自定義事件,並通過@EventListener註解或實現 ApplicationListener
介面的方式來處理這些事件。這使得在MVC架構中進行解耦和處理事件變得更加容易。
如何實現
日常中比較經典的實例場景 , 舉個例子,如博客園的文章訂閱, 當關註的作者發佈了新的文章後,關註其的粉絲就會收到消息通知,這裡將代碼拆出來如下。
import java.util.ArrayList;
import java.util.List;
// 主題介面
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers(String news);
}
// 觀察者介面
interface Observer {
void update(String news);
}
// 新聞發佈者
class NewsPublisher implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String news) {
for (Observer observer : observers) {
observer.update(news);
}
}
public void publishNews(String news) {
System.out.println("發佈新聞: " + news);
notifyObservers(news);
}
}
// 觀察者 - 讀者
class Reader implements Observer {
private String name;
public Reader(String name) {
this.name = name;
}
@Override
public void update(String news) {
System.out.println(name + " 收到新聞: " + news);
}
}
public class ObserverPatternExample {
// 創建新聞發佈者
NewsPublisher publisher = new NewsPublisher();
// 創建兩個觀察者(讀者)
Observer reader1 = new Reader("小明");
Observer reader2 = new Reader("小紅");
// 註冊觀察者
publisher.registerObserver(reader1);
publisher.registerObserver(reader2);
// 發佈新聞
publisher.publishNews("Java 21發佈了!");
publisher.publishNews("Spring Framework 更新了!");
// 讀者取消訂閱
publisher.removeObserver(reader2);
// 再次發佈新聞
publisher.publishNews("小米 su7 上線了,雷總為你開車門,快行動起來吧!");
}
}
程式運行日誌如下
發佈新聞: Java 21發佈了!
小明 收到新聞: Java 21發佈了!
小紅 收到新聞: Java 21發佈了!
發佈新聞: Spring Framework 更新了!
小明 收到新聞: Spring Framework 更新了!
小紅 收到新聞: Spring Framework 更新了!
發佈新聞: 小米 su7 上線了,雷總為你開車門,快行動起來吧!
小明 收到新聞: 小米 su7 上線了,雷總為你開車門,快行動起來吧!
結語
這裡介紹觀察者,是希望從易於理解的概念開始對 Reactive Programing
的理解,在響應式編程中多數基於觀察者模式思想演變而來,如在 Reactor 中,訂閱者(Subscriber)訂閱了數據流(Publisher),併在數據流中的元素髮生變化時接收通知。
通知機制: 在觀察者模式中,主題狀態的變化會觸發通知,通知會被髮送給所有註冊的觀察者。在Reactor中,數據流中的元素髮生變化時會觸發通知,通知會被髮送給所有訂閱了該數據流的訂閱者。
事件驅動編程: 觀察者模式和 Reactor 都支持事件驅動的編程模型。在觀察者模式中,事件源(主題)發生事件(狀態變化),並通知觀察者。在 Reactor 中,事件(數據元素)在流中傳遞,並且訂閱者可以對這些事件進行響應式地處理。