Observable(觀察者)設計模式
前言
Observable設計模式存在于許多Java API和響應式編程中。下面介紹Java中永恒的Observable模式。
-
Observable設計模式用于許多重要的Java API。一個眾所周知的示例是使用ActionListenerAPI執行操作的JButton。在這個例子中,我們ActionListener在按鈕上進行了監聽或觀察。單擊按鈕時,ActionListener將執行操作。
-
Observable模式也用于響應式編程。在反應式應用程序中使用觀察者是有道理的,因為反應式的本質是反應:當另一個進程發生時,事情就會發生。
-
Observable是一種行為設計模式。它的功能是在事件發生時執行一個動作。兩個常見的例子是按鈕點擊和通知,但這種模式還有更多用途。
例子
在Observable設計模式中,一個對象在執行操作時會通知另一個對象。為了理解該模式的價值,讓我們想象一個需要單擊按鈕并且沒有通知另一個對象的場景,如圖1所示,ActionCheck 每秒檢查一次按鈕:

請注意,ActionCheck必須每秒檢查一次按鈕。現在,想象一下,如果我們每秒對該按鈕進行多次操作檢查。您能想象這會對您的應用程序性能產生什么影響嗎?
讓Do Something按鈕通知ActionCheck.這樣,ActionCheck邏輯就不需要每秒輪詢Do Something按鈕。
Observable設計模式的元素
在下圖中,請注意觀察者模式的基礎是 Observer 接口(即觀察的對象)和 Subject(被觀察的對象)。類Newsletter implements Subject 和 Subscriber implements Observer。最后,SendEmailMain 是我們的主線程,它來觸發變化。如圖2所示

代碼
Subject
被觀察者的行為會被監聽,特殊行為會觸發事件
public interface Subject {
void addSubscriber(Observer observer);
void removeSubscriber(Observer observer);
void notifySubscribers();
}
Observer
觀察者監聽到 Subject 的特殊行為,會做對應的邏輯處理
public interface Observer {
public void update(String email);
}
Newsletter(發布者)
Newsletter 是 Subject 的實現類,它會存儲 Observer,當特殊行為發生時會通知 Observer
import java.util.ArrayList;
import java.util.List;
public class Newsletter implements Subject {
protected List<Observer> observers = new ArrayList<>();
protected String name;
protected String newEmail;
public Newsletter(String name) {
this.name = name;
}
public void addNewEmail(String newEmail) {
this.newEmail = newEmail;
// 添加了新的郵件聯系人就要通知觀察者
notifySubscribers();
}
@Override
public void addSubscriber(Observer observer) {
observers.add(observer);
}
@Override
public void removeSubscriber(Observer observer) {
observers.remove(observer);
}
@Override
public void notifySubscribers() {
observers.forEach(observer -> observer.update(newEmail));
}
}
Subscriber(訂閱者)
此類實現了Observer接口
class Subscriber implements Observer {
private String name;
public Subscriber(String name) {
this.name = name;
}
@Override
public void update(String newEmail) {
System.out.println("Email for: " + name + " | Content:" + newEmail);
}
}
SendEmailMain(測試用例)
public class SendEmailMain {
public static void main(String[] args) {
Newsletter newsLetter = new Newsletter("Java Challengers");
Observer duke = new Subscriber("Duke");
Observer juggy = new Subscriber("Juggy");
Observer dock = new Subscriber("Moby Dock");
newsLetter.addSubscriber(duke);
newsLetter.addNewEmail("Lambda Java Challenge");
newsLetter.removeSubscriber(duke);
newsLetter.addSubscriber(juggy);
newsLetter.addSubscriber(dock);
newsLetter.addNewEmail("Virtual Threads Java Challenge");
}
}


浙公網安備 33010602011771號