设计模式—— 观察者模式

来源:互联网 发布:办公文件软件 编辑:程序博客网 时间:2024/05/18 01:48

参考:http://blog.csdn.net/gnuhpc/article/details/5363672


观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

设计原则4:为了交互对象之间的松耦合设计而努力

类图:



问题:象站--气象搜集装置--多个类型的气象发布版的一个系统



代码:

我们首先定义两个接口,实现这两个接口的类就是相应的主题类--气象搜集装置以及观察者类--对应气象发布版: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(); } 我们先根据主题接口实现气象搜集装置:public class WeatherData implements Subject {     private ArrayList observers;//维护一个观察者列表    private float temperature;     private float humidity;     private float pressure;     public WeatherData() {         observers = new ArrayList(); //为了记住观察者而维护的列表,类比于报刊发行部门的订阅者列表     }     public void registerObserver(Observer o) {         observers.add(o);     }     public void removeObserver(Observer o) {         int i = observers.indexOf(o);         if (i >= 0) {             observers.remove(i);         }     }     public void notifyObservers() { //这个方法对所有注册的观察者进行通知        for (int i = 0; i < observers.size(); i++) {             Observer observer = (Observer)observers.get(i);             observer.update(temperature, humidity, pressure); //推数据        }     }     public void measurementsChanged() { //这个方法是对notifyObservers的封装        notifyObservers();     }     public void setMeasurements(float temperature, float humidity, float pressure) {         this.temperature = temperature;         this.humidity = humidity;         this.pressure = pressure;         measurementsChanged();//这个方法会进而去通知所有的观察者     }     // other WeatherData methods here     public float getTemperature() {         return temperature;     }     public float getHumidity() {         return humidity;     }     public float getPressure() {         return pressure;     } }  我们再根据观察者接口实现多种气象发布版,这里只举出一个例子,其余大同小异:public class CurrentConditionsDisplay implements Observer, DisplayElement {     private float temperature;     private float humidity;     private Subject weatherData;//维护一个主题的引用,注册观察者所用     public CurrentConditionsDisplay(Subject weatherData) {         this.weatherData = weatherData;         weatherData.registerObserver(this);//创建的时候就注册,这里也可以不进行这个,而使用 WeatherData 的registerObserver公有方法    }     public void update(float temperature, float humidity, float pressure) { //观察者留出的推送接口        this.temperature = temperature;         this.humidity = humidity;         display();     }     public void display() {         System.out.println("Current conditions: " + temperature             + "F degrees and " + humidity + "% humidity");     } } 我们测试一下这个程序:public class WeatherStation {    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);        weatherData.setMeasurements(80, 65, 30.4f);         weatherData.setMeasurements(82, 70, 29.2f);         weatherData.setMeasurements(78, 90, 29.2f);     } }


原创粉丝点击