观察者模式(Observer),又叫发布-订阅模式(Publish/Subscribe),定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。

当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象有待改变的时候,应该考虑使用观察者模式。

有个天气数据的API提供给第三方网站,要求如下:

  1. 提供温度、气压和湿度的接口
  2. 测量数据更新时,要能实时的通知给第三方

/**
 * 订阅者(观察者)抽象类,自动接受输入
 */
public abstract class Observer {

    //温度
    protected float wenDu;
    //湿度
    protected float shiDu;
    //气压
    protected float qiYa;

    /**
     * 更新网站显示的天气数据
     */
    public  void update(float wenDu, float shiDu, float qiYa) {
        this.wenDu = wenDu;
        this.shiDu = shiDu;
        this.qiYa = qiYa;
        display();
    }

    public void display() {
        System.out.println("温度"+wenDu);
        System.out.println("湿度"+shiDu);
        System.out.println("气压"+qiYa);
    }
}
/**
 * 发布者接口
 */
public interface Subject {

    /**
     * 设置数据
     */
    public void setData(float wenDu, float shiDu, float qiYa);

    /**
     * 增加一个调用API的人
     */
    public void registerObserver(Observer o);

    /**
     * 移除一个调用API的人
     */
    public void removeObserver(Observer o);

    /**
     * 通知调用API的人
     */
    public void notifyObservers();
}
/**
 * 新浪调用天气API
 */
public class Sina extends Observer {

    /**
     * 还可以做其他事
     */
}
/**
 * 百度调用天气API
 */
public class BaiDu  extends Observer{
    /**
     * 还可以做其他事
     */
}
/**
 * 天气API,更新时会自动推送新数据给第三方网站
 */
public class WeatherAPI implements Subject {
    //温度
    private float wenDu;
    //湿度
    private float shiDu;
    //气压
    private float qiYa;

    private LinkedList<Observer> list;

    public WeatherAPI() {
        this.list = new LinkedList<Observer>();
    }

    @Override
    public void setData(float wenDu, float shiDu, float qiYa) {
        this.wenDu = wenDu;
        this.shiDu = shiDu;
        this.qiYa = qiYa;
        //通知调用方更新天气数据
        notifyObservers();
    }

    @Override
    public void registerObserver(Observer o) {
        list.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        if (list.contains(o)) {
            list.remove(o);
        }
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : list) {
            observer.update(wenDu, shiDu, qiYa);
        }
    }
}
public class Client {
    public static void main(String[] args) {
        System.out.println("新浪");
        Observer sina = new Sina();
        Subject weatherAPI = new WeatherAPI();
        weatherAPI.registerObserver(sina);
        weatherAPI.setData(16,51,999);

        System.out.println("===============");
        //移除新浪
        weatherAPI.removeObserver(sina);
        System.out.println("百度");
        Observer baiDu = new BaiDu();
        weatherAPI.registerObserver(baiDu);
        weatherAPI.setData(22,66,666);
    }
}
新浪
温度16.0
湿度51.0
气压999.0
===============
百度
温度22.0
湿度66.0
气压666.0

其实回调就是观察者模式的一种。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐