观察者模式(Observer Pattern)

             

给出问题事例:有一个WeatherData对象可以给我们提供实时的天气情况(温度、湿度、气压),我们要做的就是一个应用,这个应用目前有三个布告板,分别显示目前的状况、气象统计以及简单的预报。这三个布告板可以根据WeatherData的实时值进行实时更新。这个系统必须可扩展,让其他开发人员建立定制的布告板,用户可以随心所欲的删除或者添加布告板。

下面给出了WeatherData的类结构:

WeatherData

//以下给出了三个方法,分别获得温度、湿度、气压

getTemperature();

getHumidity();

getPressure();

//一旦气象更新,这个方法会被调用

measurementsChanged();

我们貌似很快就能找到解决办法:

public  class WeatherData{

              //实例变量声明。

             public void measurementsChanged(){

                           float temp=getTemperature();

                           float humidity=getHumidity();

                           float pressure=getPressure();


                    currentConditionDislplay.update(temp,humidity,pressure);

                          statisticsDisplay.update(temp,humidity,pressure);

                          forecastDisplay.update(temp,humidity,pressure);

           }

}

仔细分析下,我们的实现有什么不对吗?

对,就是那些蓝色部分,想想我们讲的策略模式,这就是针对实现编程,这样会导致我们以后增加或者删除布告板时必须修改程序。

好的,这时候我们主角就应该上场了,那就是观察者模式。我们首先给出观察者模式的定义:观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象的状态改变时,它的所有依赖者都能收到通知并立即自动更新。

我们将观察者模式中的两种对象分别命名为主题对象和观察者对象。主题对象就是我们定义里的“一”,观察者对象就是我们定义里的“多”。多主题对象的状态改变时,主题对象的所有依赖者(即观察者)都能收到通知并自动更新。有没有想起来Android里的广播?下面我们举个小例子来说明主题和观察者。假如一个主题对象的观察者有猫对象,狗对象,老虎对象。而老鼠对象不依赖主题对象。当主题对象改变时,猫对象、狗对象以及老虎对象会收到通知,而老鼠对象不会收到通知。如果老鼠对象想收到通知,它必须在主题对象里进行注册。如果猫对象不想再收到通知,它可以告诉主题对象,主题对象知道猫的请求之后,把它从观察者中删除,则猫对象今后就不会再收到通知。

观察者提供了一种对象设计,让主题和观察者之间松耦合。

所以我们给出了第四个设计原则:

为了交互对象之间的松耦合设计而努力。

OK,下面我们开始使用观察者模式重新设计我们的实现。让我们先从接口开始。

public interface Subject{

              //以下两个方法都需要一个观察者作为参数,该观察者是用来注册或者删除的。

           public void registerObserver(Observer o);

              public  void removerObserver(Observer o);

             //当主题状态改变时,这个方法会被调用,以通知所有的观察者。

             public  void notigyObservers();

}

public interface Observer{

           / /所有的观察者都要实现这个方法,以实现观察者接口。当气象观测值改变时,主题会传递这些状态值。

         public void update(float temp,float humidity,float pressure);

}

public void displayElement{

            //当布告板需要显示时,调用此方法。

            public void display();

}

下面我们使用观察者模式来实现WeatherData

public class WeatherData implements Subject{//WeatherData现在实现了Subject接口。

              private ArrayList<Observer> observers; //用来记录观察者。

              private float temperature;

              private float humidity;

              private float pressure;

              public WeatherData(){

                            observers=newArrayList()<Observer>;

              }

              public void registerObserver(Observer o){

                             observers.add(o);

               }

              public void removerObserver(Observer o){

                             inti=observers.indexOf(o);

                             if(i>=0){

                                   observers.remove(i);

                              }

               }

             public void notigyObservers(){

                           for(Observero:observers){

                                    o.update(temperature,humidity,pressure);

                           }

               }

             //从气象站得到更新的值时,通知观察者。

            public void measurementsChanged(){

                          notigyObservers();

            }

           public void setMeasurements(float temperature,float humidity,floatpressure){

                         this.temperature=tempreture;

                         this.humidity=humidity;

                        this.pressure=pressure;

                         measurementsChanged();

            }

}

接下来,我们来建立我们的布告板。我这里只实现当前状态布告板,其他的两个大家可以自己动手实现。

public class CurrentConditionsDisplay implements Observer,DisplayElement{

                 private float temperature;

                 private float humidity;

                private float pressure;

                private Subject weatherData;


               public CurrentConditionDisplay(Subject weatherData){

                             this.weatherData=weatherData;

                           //注册自己为观察者

                          weatherData.registerObserver(this);

              }

             public void updata(float temperature,float humidity,float pressure){

                           this.temperature=temperature;

                            this.humidity=humidity;

                            this.pressure=pressure;

                           display();

              }

             public void display(){

                           System.out.println(“Currentconditions:”+temperature+”F degress”+humidity+”%humidity”+pressure+”% pressure);

             }

}

写一个测试程序。

public class WeatherStation{

             public static void main(String[] args){

                         WeatherData weatherData=new WeatherData();

                          CurrentConditionsDisplay currentConditionsDisplay=new CurrentConditionsDisplay(weatherData);

                           StatisticsDisplay statisticsDisplay=new StatisticsDisplay(weatherData);

                          ForecastDisplay forecastDisplay=new ForecastDisplay(weatherData);


                          weatherData.setMeasurements(30,60,30.4f);

                          weatherData.setMeasurements(40,50,50.4f);

                          weatherData.setMeasurements(35,40,20.4f);

              }

}

程序的输出大家应该都很清楚了。



你可能感兴趣的:(编程,android,String,Class,float,interface)