观察者模式(发布订阅模式)

推送模式:

  • CurrentCondition

    • /**
       * 显示当前天气情况(是调用天气数据的本体
       */
      public class CurrentConditions {
          private float temperature;//温度
          private float pressure;//气压
          private float humidity;//湿度
      
          public void update(float temperature, float pressure, float humidity) {
              this.temperature = temperature;
              this.pressure = pressure;
              this.humidity = humidity;
              display();
          }
      
          public void display() {
              System.out.println("***Today mTemperature: " + temperature + "***");
              System.out.println("***Today mPressure: " + pressure + "***");
              System.out.println("***Today mHumidity: " + humidity + "***");
          }
      }
      
  • WeatherData

    • public class WeatherData {
          private float temperatrue;
          private float pressure;
          private float humidity;
          private CurrentConditions currentConditions;
      
          public WeatherData(CurrentConditions currentConditions) {
              this.currentConditions = currentConditions;
          }
      
          public float getTemperature() {
              return temperatrue;
          }
      
          public float getPressure() {
              return pressure;
          }
      
          public float getHumidity() {
              return humidity;
          }
      
          public void dataChange() {
              currentConditions.update(getTemperature(), getPressure(), getHumidity());
          }
      
          public void setData(float temperature, float pressure, float humidity) {
              this.temperatrue = temperature;
              this.pressure = pressure;
              this.humidity = humidity;
              dataChange();
          }
      }
      
      
  • InternetWeather

    • public class InternetWeather {
          public static void main(String[] args) {
              CurrentConditions currentConditions = new CurrentConditions();
              WeatherData weatherData = new WeatherData(currentConditions);
              weatherData.setData(30, 150, 40);
          }
      }
      

InternetWeather这个类的作用就是给WeatherData赋值,然后WeatherData推送给各个订阅者。

但是坏处是显而易见的。每当要加入一个第三方需要用到WeatherData的数据时,就要在WeatherData的dataChange方法里添加第三方,这违反了开闭原则。

运用观察者设计模式改进
  • Subject(作为发布者的接口)

    • public interface Subject {
      
          public void registerObserver(Observer o);
          public void removeObserver(Observer o);
          public void notifyObservers();
      }
      
  • Observer(作为观察者的接口)

    • public interface Observer {
          public void update(float temperature,float pressure,float humidity);
      }
      
  • Tencent(观察者的具体实现类)

    • /**
       * 显示当前天气情况(是调用天气数据的本体
       */
      public class Tencent implements Observer {
          private float temperature;//温度
          private float pressure;//气压
          private float humidity;//湿度
      
          public void update(float temperature, float pressure, float humidity) {
              this.temperature = temperature;
              this.pressure = pressure;
              this.humidity = humidity;
              display();
          }
      
          public void display() {
              System.out.println("***Today mTemperature: " + temperature + "***");
              System.out.println("***Today mPressure: " + pressure + "***");
              System.out.println("***Today mHumidity: " + humidity + "***");
          }
      }
      
  • Ali(观察者的具体实现类)

    • public class Ali implements Observer{
          @Override
          public void update(float temperature, float pressure, float humidity) {
              System.out.println(temperature+'\t'+pressure+'\t'+humidity);
          }
      }
      
  • WeatherData(作为发布者的具体实现类)

    • public class WeatherData implements Subject{
          private float temperatrue;
          private float pressure;
          private float humidity;
      
          private ArrayList<Observer> observers;
      
          public WeatherData() {
              observers = new ArrayList<Observer>();
          }
      
          public float getTemperature() {
              return temperatrue;
          }
      
          public float getPressure() {
              return pressure;
          }
      
          public float getHumidity() {
              return humidity;
          }
      
          public void dataChange() {
              notifyObservers();
      
          }
      
          public void setData(float temperature, float pressure, float humidity) {
              this.temperatrue = temperature;
              this.pressure = pressure;
              this.humidity = humidity;
              dataChange();
          }
      
          @Override
          public void registerObserver(Observer o) {
              observers.add(o);
          }
      
          @Override
          public void removeObserver(Observer o) {
              if (observers.contains(o)){
                  observers.remove(o);
              }
          }
      
          @Override
          public void notifyObservers() {
              for (int i = 0;i < observers.size();i++){
                  observers.get(i).update(this.temperatrue,this.pressure,this.humidity);
              }
          }
      }
      
  • Client

    • public class Client {
          public static void main(String[] args) {
              WeatherData weatherData = new WeatherData();
              Tencent tencent = new Tencent();
              weatherData.registerObserver(tencent);
              Ali ali = new Ali();
              weatherData.registerObserver(ali);
              weatherData.setData(12f,4f,5f);
          }
      }
      
      

运行Client,得到结果如下

***Today mTemperature: 12.0***
***Today mPressure: 4.0***
***Today mHumidity: 5.0***
 12.0	4.0	5.0

观察者模式的要害在于,Tencent类和Ali类共同实现了一个Observer类,这意味着它们两者成为了同样的类。这样就会产生共同的接口,于是发布者(Subject类)就可以通过调用Observer类的抽象方法来为每一个具体实例服务了。

还有一个要点是ArrayList,多个观察者的注册,需要用到ArrayList进行存储。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值