• 尚硅谷设计模式-观察者模式



    笔记来源:尚硅谷

    一、需求

    天气预报项目需求,具体要求如下:

    1. 气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如
      发布到自己的网站或第三方)。
    2. 需要设计开放型API,便于其他第三方也能接入气象站获取数据。
    3. 提供温度、气压和湿度的接口
    4. 测量数据更新时,要能实时的通知给第三方

    二、解决方案

    2.1 普通方案

    1. 网站调用的气象站dataChange()

    2. 当数据定时更新时,气象站数据更新后,调用网站的update(),推送到网站

      //可以理解成气象站自己的网站
      public class CurrentConditions {
          private float temperature;//温度
          private float pressure;//气压
          private float humidity;//湿度
          
          //更新天气情况,由 WeatherData 调用(推送模式)
          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 + "***");
          }
      }
      
      /**
       *  1.包含最新的天气信息
       *  2. 含有CurrentConditions对象
       *  3. 当数据更新时,主动调用update
       */
      public class WeatherData {
      	private float temperatrue;
      	private float pressure;
      	private float humidity;
      	private CurrentConditions currentConditions;
      
      	public WeatherData (CurrentConditions currentConditions) {
      		this.currentConditions = currentConditions ;
      	}
      
      	/*省略get set*/
          
      	public void dataChange() {
              //调用网站update方法
      		currentConditions.update(getTemperatrue(), getPressure(), getHumidity());
      	}
      	
          //当数据更新时调用setData,更新WeatherData
          public void setData(float temperatrue, float pressure, float humidity){
              this.humidity = humidity;
              this.pressure = pressure;
              this.temperatrue = temperatrue;
              //推送最新数据给网站
              dataChange();
          }
      	
      }
      

      调用过程如下:

      public class Client {
      	public static void main(String[] args) {
      		//创建接入方currentConditions
      		CurrentConditions currentConditions = new CurrentConditions();
      		//创建WeatherData并将接入方currentConditions传递到WeatherData中
      		WeatherData weatherData = new WeatherData(currentConditions);
      		//更新天气情况
      		weatherData.setData(30, 150, 40);
      	}
      }
      

    问题分析:

    当添加多个第三方时,会修改WeatherData类中的大量方法,不利于维护,不能动态添加

    2.2 观察者模式

    观察者模式类似于订牛奶业务

    1. 奶站/气象局:Subject – 登记,注册,移除,通知
    2. 用户/第三方网站:Observer – 接受输入方,有更新方法

    ➢观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer, Subject通知Observer变化,比如这里的奶站Subject,是1的一方。用户时Observer,是多的一方。

    public interface Subject {
    	public void registerObserver (Observer o);
    	public void remove0bserver (observer o);
    	public void notifyObservers();
    }
    
    //观察者接口,由观察者实现
    public interface Observer {
    	public void update(float temperatrue, float pressure, float huminity );
    }
    
    //百度,实现观察者接口
    public class Baidu implements Observer {
    
    	private float temperature;
    	private float pressure;
    	private float humidity;
    
    	public void display() {
    		System.out.println("***Today mTemperature:" + temperature +"***");
    		System.out.println("***Today mPressure: " + pressure + "***");
    		System.out.println("***Today mHumidity: " + humidity + "***");
    	}
    
    	@Override
    	public void update(float temperature, float pressure, float humidity) {
    		this.temperature = temperature;
    		this.pressure = pressure;
    		this.humidity = humidity;
    		display();
    	}
    }
    
    /**
     *  1.包含最新的天气信息
     *  2. 含有 观察者集合
     *  3. 当数据更新时,通知所有接入方,让他们看到最新消息
     */
    public class WeatherData implements Subject{
        private float temperature;
        private float pressure;
        private float humidity;
        private List<Observer> observers;
    
        public WeatherData () {
            this.observers = new ArrayList<Observer>();
        }
    
        /*省略get set*/
    
        @Override
        public void registerObserver(Observer o) {
            observers.add(o);
    
        }
    
        @Override
        public void remove0bserver(Observer o) {
            observers.remove(o);
    
        }
    
        @Override
        public void notifyObservers() {
            for(Observer observer : observers) {
                observer.update(temperature, pressure, humidity);
            }		
        }
    
        public void setData(float temperatrue, float pressure, float humidity){
            this.humidity = humidity;
            this.pressure = pressure;
            this.temperature = temperatrue;
            notifyObservers();
        }
    }
    

    调用时可以动态添加观察者,可维护性大大增强

  • 相关阅读:
    Go 函数方法
    rz上传文件乱码
    pip问题:ImportError: cannot import name main
    docker启动报错 docker: Error response from daemon: OCI runtime create failed: container_linux.go:348
    python遍历列表删除多个元素的坑
    python写入csv文件时的乱码问题
    python中的exec()函数和eval()函数
    tornado的IOLoop.instance()方法和IOLoop.current()方法区别
    安装mysql-python时报错
    python将科学计数法表示的数值的字符串转换成数值型数据
  • 原文地址:https://www.cnblogs.com/theory/p/13338730.html
Copyright © 2020-2023  润新知