阿爾法的身體內部有一個智能芯片,這個芯片能夠根據環境和需求自動改變它的行為模式。當阿爾法需要完成不同任務時,它的內部狀態會發生變化,進而改變它的行為,就像是它變成了另一個機器人一樣。
一天,智能城的市長接到一個緊急消息:城市的能源核心出了問題,導致整個城市即將陷入黑暗。市長知道只有阿爾法才能解決這個問題,于是他立刻派人去找阿爾法。
阿爾法接到任務后,立即進入“修理模式”。在修理模式下,阿爾法的內部狀態變為“工程師狀態”,它的手臂變成了各種工具,眼睛變成了高精度的掃描儀。阿爾法迅速來到了能源核心,開始檢測問題所在。
經過一番檢查,阿爾法發現問題出在能源核心的控制系統上。它決定進入“編程模式”。在編程模式下,阿爾法的內部狀態變為“程序員狀態”,它的手指變成了鍵盤和電纜接口,能夠直接連接到控制系統并進行編程。
阿爾法快速編寫了一段修復程序,上傳到控制系統中。隨著程序的運行,能源核心漸漸恢復了正常,整個智能城重新亮起了光芒。
然而,阿爾法的任務并沒有結束。智能城的一所學校發生了火災,學生們被困在教學樓里。阿爾法接到新的任務后,立即進入“救援模式”。在救援模式下,阿爾法的內部狀態變為“救援狀態”,它的身體變得更加堅固,裝備了各種救援工具和滅火設備。
阿爾法迅速趕到現場,使用滅火器撲滅了火焰,隨后用強有力的臂膀破開被困學生們的教室門,將他們一個個安全地帶了出來。
觀察者模式(Observer Pattern)
狀態模式(State Pattern)是一種行為設計模式,它允許一個對象在其內部狀態改變時改變它的行為。這種模式通過將狀態相關的行為封裝在狀態對象中,使得當對象的內部狀態改變時,其行為也會隨之改變,類似于它改變了其類。
核心組件
- Subject(主題):主題保存了一組觀察者,提供用于增加或刪除觀察者的接口。
- Observer(觀察者):為那些在主題狀態改變時需要獲得通知的對象定義一個更新接口。
- ConcreteSubject(具體主題):存儲具體觀察者關心的數據,發送通知給觀察者,通常包含對具體數據的增刪改操作。
- ConcreteObserver(具體觀察者):實現觀察者接口,以便在得到通知時更新自身。
適用場景
- 當一個抽象模型有兩個方面,其中一個方面依賴于另一個方面時:
- 觀察者模式允許你獨立地擴展或復用核心功能。
- 當對一個對象的改變需要同時改變其他對象,而不知道具體有多少對象需要改變時:
- 觀察者模式可以讓你在不修改這些類的前提下增加新的觀察者。
- 當一個對象必須通知其他對象,但你希望避免做成這些對象之間的緊密耦合時:
- 觀察者模式提供了一種松耦合的設計解決方案。
實現實例
以新聞應用為例,其中新聞發布系統(主題)需要通知所有訂閱者(觀察者)新聞更新。
主題接口(Subject Interface)
定義了附加和刪除觀察者的方法,以及通知觀察者的方法。
public interface Subject {void registerObserver(Observer o);void removeObserver(Observer o);void notifyObservers();
}
具體主題(Concrete Subject)
存儲狀態,并在狀態改變時通知觀察者。
public class NewsAgency implements Subject {private List<Observer> observers = new ArrayList<>();private String news;public void registerObserver(Observer o) {observers.add(o);}public void removeObserver(Observer o) {observers.remove(o);}public void notifyObservers() {for (Observer observer : observers) {observer.update(news);}}public void setNews(String news) {this.news = news;notifyObservers();}
}
觀察者接口(Observer Interface)
定義更新接口,用于獲取狀態改變通知。
public interface Observer {void update(String news);
}
具體觀察者(Concrete Observer)
實現觀察者接口,根據通知更新自己。
public class NewsChannel implements Observer {private String news;@Overridepublic void update(String news) {this.news = news;System.out.println("News Updated: " + news);}
}
客戶端代碼(Client Code)
演示如何使用觀察者模式。
public class Client {public static void main(String[] args) {NewsAgency newsAgency = new NewsAgency();NewsChannel channel = new NewsChannel();newsAgency.registerObserver(channel);newsAgency.setNews("New update on AI technology!");}
}
優缺點
優點
- 支持廣播通信:
- 觀察者模式提供了一種訂閱機制,可以實現消息的廣播。
- 應用松耦合:
- 主題與觀察者之間使用抽象耦合,可以輕松地添加新的觀察者。
缺點
- 可能引發無序的更新:
- 如果觀察者的更新方法引發循環依賴,可能導致系統行為難以預測。
- 當觀察者和主題之間的依賴關系復雜時,可能需要額外的維護成本。
類圖
+----------------+ +------------------+
| Subject |-------->| Observer |
+----------------+ +------------------+
| + registerObserver() | + update() |
| + removeObserver() | |
| + notifyObservers() +------------------+
+----------------+ |
| | |
+----------------+ ||+-------------------+--------+----------------+| | | |
+---------------+ +-----------------+ +----------------+ +--------------+
|ConcreteSubject| |ConcreteObserver1| |ConcreteObserver2| | ... |
+---------------+ +-----------------+ +----------------+ +--------------+
| + setNews() | | + update() | | + update() | | + update() |
+---------------+ +-----------------+ +----------------+ +--------------+
總結
觀察者模式提供了一種優雅的方式來實現對象間的通信,特別適用于狀態變化需要通知多個對象的場景。通過將主題與觀察者解耦,增加了系統的靈活性和可擴展性,同時也需注意避免循環依賴和更新順序問題。