二.观察者模式(observer)

二.观察者模式(observer)

根据气象站的数据来显示天气预报

其实这个系统分成三部分

1.   气象站(获取气象数据的物理装置)

2.   WeatherData对象(追踪气象站数据,并更新布告板)

3.   布告板(当前的天气状况)

 

WeatherData类的介绍

有个四个method:

温度:getTemperature()

湿度:getHumidity()

气压:getPressure()

mentsChanged():气象参数更新时,这个方法被调用,也就是我们开发代码实装在这个里面

 

错误的示范:

         publicvoid mentsChanged() {

 

                   floattemp = getTemperature();

                   floathumidity = getHumidity();

                   floatpressure = getPressure();

                  

                   condision1Display.update(temp,humidity,pressure);

                   condision2Display.update(temp,humidity,pressure;

                   condision3Display.update(temp,humidity,pressure);

         }

这样做的问题是,每增加或删除一个布告板都会去改动mentsChanged方法。

 

 

下面来认识观察者模式:

先举一个例子报纸订阅的问题来类比观察者模式

1.   报社的业务就是出版报纸,每种报纸算一个主题(subject)

2.   你向这家报社订阅报纸,你就成为订户,也就是一个观察者(observer)

只要他们有新报纸出版,你就会收到,也就相当也主题有更新,观察者就会收到通知

3.   当你不再想看报纸的时候,就取消订阅,他们就不会送报纸过来了

就是你解除依赖,不再是观察者了

 

观察者模式:它定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

 

类图介绍:

// 主题接口

interface Subject {

         //注册为观察者

         abstractvoid registerObserver();

         //从观察者中删除

         abstractvoid removeObserver();

         //更新当前所有观察者

         abstractvoid notifyObservers();

}

// 观察者接口

interface Subject {

         //当主题改变时被调用

         abstractvoid update();

}

 

松耦合概念的介绍

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

为什么这么说呢?

1.   主题只知道观察者实现了observer接口,其他关于观察者的具体类是什么,做了什么它并不关心。

2.   主题唯一依赖的东西是一个实现observer接口的对象列表,所以我们可以随时增加观察者。

松耦合的设计之所以能让我们建立有弹性的oo系统,能够应对变化,是因为对象之间的互相依赖降到了最低。

开始实现气象站:

主题接口:

public interface Subject {

         //

         publicvoid registerObserver(Observer o);

         //

         publicvoid removeObserver(Observer o);

         //

         publicvoid notifyObservers();

}

观察者接口:

publicinterface Observer {

         //

         publicvoid update(floattemp, floathumidity, floatpressure);

}

显示接口:

publicinterface DisplayElement {

         //

         publicvoid display();

}

气象对象:

publicclass WeatherData implementsSubject{

         //观察者列表

         privateArrayList<Observer> observers;

         //

         privatefloattemperature;

         //

         privatefloathumidity;

         //

         privatefloatpressure;

         //

         public WeatherData(){

                   observers= new ArrayList<Observer>();

         }

         //

         publicvoid registerObserver(Observer o){

                   observers.add(o);

         }

         //

         publicvoid removeObserver(Observer o){

                   intindex = observers.indexOf(o);

                   if (index >= 0) {

                            observers.remove(index);

                   }

         }

         //

         publicvoid notifyObservers(){

                   for (inti = 0; i < observers.size(); i++) {

                            Observer observer = (Observer) observers.get(i);

                            observer.update(temperature, humidity, pressure);

                   }

         }

         //气象参数变化时,通知全部观察者

         publicvoid mentsChanged(){

                   notifyObservers();

         }

         //手动改变其实参数来更新布告板

         publicvoid setMents(floattemperature, floathumidity, floatpressure) {

                   this.temperature = temperature;

                   this.humidity = humidity;

                   this.pressure = pressure;

                   mentsChanged();

         }

}

一号布告板:

publicclass Condition1Display implements Observer,DisplayElement{

         //

         privatefloattemperature;

         //

         privatefloathumidity;

         //

         privatefloatpressure;

         //

         private Subject weatherData;

         //

         public Condition1Display(SubjectweatherData) {

                   this.weatherData = weatherData;

                   weatherData.registerObserver(this);

         }

         //

         publicvoid update(floattemp, floathumidity, floatpressure){

                   this.temperature = temp;

                   this.humidity = humidity;

                   this.pressure = pressure;

                   //

                   display();

         }

         //显示气象参数

         publicvoid display() {

                   System.out.println("temperature:" + temperature + "," + "humidity:" + humidity + "," + "pressure:" + pressure);

         }

}

//测试

publicclass WeatherDataTest {

         publicstaticvoid main(String[] args) {

                   //天气对象

                   WeatherData weatherData = new WeatherData();

                   //注册一个布告板

                   Condition1Display condition1Display1 = newCondition1Display(weatherData);

                   //再注册一个布告板

                   Condition1Display condition1Display2= new Condition1Display(weatherData);

                   //天气参数改变

                   weatherData.setMents(10,20, 30);

         }

}

注意一点:有多个观察者的时候,不可有依赖于特定的通知顺序。

Swing大量使用了观察者模式,例如给button追加listener

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值