本文參考Head First設計模式一書,感覺書中的例子實在很好,很貼切。對模式的知識點進行總結,并對書的源碼做了一定注釋。
觀察者模式要點有二:主題和觀察者。
最貼切的案例是:雜志訂閱,雜志是主題,觀察者是訂閱者。當出版新雜志時候,這個事件會自動通知所有的訂閱者。
根據OO基本原則,應該針對接口程式設計(當然原因很多),主題和訂閱者一般都作為接口。
下面是Head First的例子,是一個氣象站,使用者訂閱氣象資訊的服務。
并且,最終使用者所要的資訊可能是:
針對這個需求,應用觀察者模式來實作:
但是這個隻是一個主題與觀察者的設計,觀察者自身還需要将資訊顯示出去。那麼再用一個接口,專門來實作展示的功能。
實際上,上面的DisplayElement接口用再此處,本質上是政策模式的應用。
了解每個模式的特點對交流和設計都有很大幫助,當OO思想境修煉到很高的程度時,應該是忘掉所有的模式,而可以根據需要做出最佳設計,這個程度可以算手中無劍,心中有劍的地步。
下面是源碼,隻列出接口:
/**
* 主題
*/
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
* 觀察者
public interface Observer {
public void update(float temp, float humidity, float pressure);
* 布告闆
public interface DisplayElement {
public void display();
測試main方法:
public static void main(String[] args) {
//建立主題
WeatherData weatherData = new WeatherData();
//建立三個觀察者
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData);
//進行氣象測量,主題的狀态會因為測量值而改變
weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(82, 70, 29.2f);
weatherData.setMeasurements(78, 90, 29.2f);
}
本例僅僅是為了說明這種模式,設計還遠不夠完美。實際上,主題中應該有一個線程去掃描狀态的變化,當變化了,自動去調用measurementsChanged()方法。
觀察者模式使用很普遍,GUI程式設計中事件注冊就是典型的觀察者模式的應用。
以上是自己實作的觀察者模式,下文将講述JDK所實作的觀察者模式。
本文轉自 leizhimin 51CTO部落格,原文連結:http://blog.51cto.com/lavasoft/201617,如需轉載請自行聯系原作者