观察者模式

天气预报的项目需求

使用普通的推送方式实现(代码)

package com.observer;

/**
 * 这个是核心类(可以理解成气象观测站,他这里有最新的天气情况)
 * 1.包含最新的天气情况信息
 * 2.含有CurrentConditions 对象
 * 3.当数据有更新的时候,就主动的调用 CurrentConditions 对象的 update方法(含display方法),这样他们(接入方)就看到了最新的信息
 *
 */
public class WeatherData {
    private float temperature;//温度
    private float pressure;//气压
    private float humidity;//湿度
    private CurrentConditions currentConditions;

    public WeatherData(CurrentConditions currentConditions){
        this.currentConditions=currentConditions;
    }
    public float getTemperature() {
        return temperature;
    }

    public float getPressure() {
        return pressure;
    }

    public float getHumidity() {
        return humidity;
    }

    public void dataChange(){
        //调用接入方的update()
        currentConditions.update(getTemperature(),getPressure(),getHumidity());
    }
    //当有数据更新的时候,就调用setData
    public void setData(float temperature,float pressure,float humidity){
        this.temperature=temperature;
        this.pressure=pressure;
        this.humidity=humidity;
        //调用dataChange,将最新的信息 推送给 接入方(也就是currentConditions)
        dataChange();
    }


}

  

package com.observer;

/**
 * 显示当前天气情况(可以理解成是气象局自己的网站需要展示天气情况【当然还有百度、新浪等网站也需要展现天气情况】)
 */
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();
    }

    //显示
    private void display() {
        System.out.println("today temperature:"+temperature);
        System.out.println("today pressure:"+pressure);
        System.out.println("today humidity:"+humidity);
    }

}

  

package com.observer;

import com.alibaba.fastjson.JSON;

import java.util.Map;

/**
 * 模拟客户端进行调用
 */
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,100,50);
        //天气发生变化
        System.out.println("=====天气发生变化=====");
        weatherData.setData(20,200,60);

    }
}

  

运行结果:

today temperature:30.0
today pressure:100.0
today humidity:50.0
=====天气发生变化=====
today temperature:20.0
today pressure:200.0
today humidity:60.0

  

普通方案存在的问题

使用观察者模式

使用观察模式解决天气预报的需求

代码

package com.observer.improve;
//接口,让WeatherData来实现
public interface Subject {
    public void registerObserver(Observer observer);
    public void removeObserver(Observer observer);
    public void notifyObservers();
}

  

package com.observer.improve;

import com.observer.CurrentConditions;

import java.util.ArrayList;

/**
 * 这个是核心类(可以理解成气象观测站,他这里有最新的天气情况)
 * 1.包含最新的天气情况信息
 * 2.含有观察者集合,使用Arraylist管理
 * 3.当数据有更新的时候,就主动的调用 Arraylist, 通知所有的接入方,就能够看到最新的信息
 */
public class WeatherData implements Subject {
    private float temperature;//温度
    private float pressure;//气压
    private float humidity;//湿度
    private ArrayList<Observer> observers;//观察者集合

    public WeatherData() {
        observers = new ArrayList<Observer>();
    }

    public float getTemperature() {
        return temperature;
    }

    public float getPressure() {
        return pressure;
    }

    public float getHumidity() {
        return humidity;
    }

    public void dataChange() {
        //调用接入方的update()
        notifyObservers();
    }

    //当有数据更新的时候,就调用setData
    public void setData(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        //调用dataChange,将最新的信息 推送给 接入方(也就是currentConditions)
        dataChange();
    }

    //下面这三个是核心的方法

    /**
     * 注册一个观察者
     *
     * @param observer
     */
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    /**
     * 移除一个观察者
     *
     * @param observer
     */
    @Override
    public void removeObserver(Observer observer) {
        if (observers.contains(observer)) {
            observers.remove(observer);
        }
    }

    /**
     * 遍历所有的观察者,并进行通知
     */
    @Override
    public void notifyObservers() {
        for (int i = 0; i <observers.size() ; i++) {
            observers.get(i).update(this.temperature,this.pressure,this.humidity);
        }
    }
}

  

package com.observer.improve;
//观察者接口,由观察者来实现
public interface Observer {
    public void update(float temperature,float pressure,float humidity);
}

  

package com.observer.improve;

/**
 * 显示当前天气情况(可以理解成是气象局自己的网站需要展示天气情况【当然还有百度、新浪等网站也需要展现天气情况】)
 */
public class CurrentConditions implements Observer{
    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();
    }

    //显示
    private void display() {
        System.out.println("today temperature:"+temperature);
        System.out.println("today pressure:"+pressure);
        System.out.println("today humidity:"+humidity);
    }

}

  

package com.observer.improve;

/**
 * 百度网站
 * 显示当前天气情况(可以理解成是气象局自己的网站需要展示天气情况【当然还有百度、新浪等网站也需要展现天气情况】)
 */
public class BaiduCurrentConditions implements Observer{
    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();
    }

    //显示
    private void display() {
        System.out.println("百度首页气象信息");
        System.out.println("baidu today temperature:"+temperature);
        System.out.println("baidu today pressure:"+pressure);
        System.out.println("baidu today humidity:"+humidity);
    }

}

  

package com.observer.improve;


public class Client {
    public static void main(String[] args) {
        //创建一个weatherdata
        WeatherData weatherData = new WeatherData();
        //创建一个观察者
        CurrentConditions currentConditions = new CurrentConditions();
        BaiduCurrentConditions baiduCurrentConditions = new BaiduCurrentConditions();
        //将观察者注册到weatherdata中
        weatherData.registerObserver(currentConditions);
        weatherData.registerObserver(baiduCurrentConditions);
        //测试
        System.out.println("通知各个注册的观察者,看看收到的信息");
        weatherData.setData(10,100,32);
        weatherData.removeObserver(currentConditions);
        System.out.println("通知各个注册的观察者,看看收到的信息");
        weatherData.setData(10,100,32);

    }
}

  

运行结果:

通知各个注册的观察者,看看收到的信息
today temperature:10.0
today pressure:100.0
today humidity:32.0
百度首页气象信息
baidu today temperature:10.0
baidu today pressure:100.0
baidu today humidity:32.0
通知各个注册的观察者,看看收到的信息
百度首页气象信息
baidu today temperature:10.0
baidu today pressure:100.0
baidu today humidity:32.0

  

观察者模式的好处

 

原文地址:https://www.cnblogs.com/dongyaotou/p/15237947.html