天天看點

設計模式-觀察者模式(上)

本文參考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,如需轉載請自行聯系原作者