java设计模式-观察者模式

java设计模式-观察者模式

一、了解观察者模式

1.1 什么是观察者模式

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

典型的问题比如报社,只要你是他们的订户,他们每次有新报纸出版时,就会向你这送来,当你不想要看报纸时,取消订阅,他们就不会再给你送报纸。

1.2 观察者模式组成结构

  • 抽象主题 (Subject):抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
  • 具体主题 (ConcreteSubject):该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  • 抽象观察者 (Observer):是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
  • 具体观察者 (ConcrereObserver):实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

1.3 观察者模式 UML 图解

在这里插入图片描述
二、观察者模式具体应用

2.1 问题描述

气象观测站系统:该系统中包含三部分,分别是气象站 (获取实际气象数据的物理装置)、WeatherData 对象 (追踪气象站的数据,并更新布告板) 和布告板 (显示天气状况给用户看,布告板共有两个,分别显示当前的温度以及对天气进行预告)。

2.2 问题分析

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DvCaSOHH-1606153132212)(C:\Users\leigege\AppData\Roaming\Typora\typora-user-images\1605784272682.png)]

2.4 代码实现

PS:代码模块较多,建议将这些代码拷下来运行一遍。

抽象主题接口 Subject

public interface Subject {
    /**
     *  注册观察者
     *  
     * @param observer 观察者对象
     */
    void registObserver(Observer observer);

    /**
     *  移除观察者
     *
     * @param observer 观察者对象
     */
    void removeObserver(Observer observer);

    /**
     * 当主题状态改变时,这个方法会被调用,通知所有的观察者
     */
    void notifyObservers();
}

抽象观察者接口 Observer

public interface Observer {

    /**
     * 当气象观测值改变时,主题会把这些状态值作为参数,传送给观察者
     * 
     * @param temp 温度
     * @param humidity  湿度
     * @param pressure  压力
     */
    void update(float temp, float humidity, float pressure);
}

具体的观察者

public class CurrentConditions implements Observer{
    //气温,气压,湿度
    private float temperature;
    private float humidity;
    private float pressure;


    //更新
    @Override
    public void update(float temp, float humidity, float pressure) {
            this.temperature=temp;
            this.humidity=humidity;
            this.pressure=pressure;
            display();
    }

    //显示
    public void display() {
        System.out.println("Current conditions list : " + "温度 = " +
                temperature + ", 湿度 = " + humidity + ", 气压 = " + pressure);
    }
}

具体的主题 气象站发布天气

public class WeatherData implements Subject{
    //气温,气压,湿度
    private float temperature;
    private float humidity;
    private float pressure;
    //观察者集合 
    private ArrayList<Observer> observers;

    public WeatherData() {
        observers=new ArrayList<>();
    }
	//添加观察者  订阅的
    @Override
    public void registObserver(Observer observer) {
            observers.add(observer);
    }
	//移除观察者 取消订阅
    @Override
    public void removeObserver(Observer observer) {
        //查询集合中是否存在observer
        if (observers.contains(observer)){
            observers.remove(observer);}
    }
	//通知方法
    @Override
    public void notifyObserver() {
        for (Observer observer:observers){
            observer.update(this.temperature,this.humidity,this.pressure);
        }
    }
    //设置值 每次设置都会调用改变方法 然后进行通知
    public void setData(float temperature,float pressure,float humidity){
        this.temperature=temperature;
        this.pressure=pressure;
        this.humidity=humidity;
        //调用方法,将最新的信息推送给接入方
        dataChange();
    }
    public void dataChange(){
        notifyObserver();
    }
}

如果需要添加订阅者 只需要实现 订阅者接口 从发布者中添加

//网易天气
public class Wangyitianqi implements Observer{
    //气温,气压,湿度
    private float temperature;
    private float humidity;
    private float pressure;


    //更新
    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temperature=temp;
        this.humidity=humidity;
        this.pressure=pressure;
        display();
    }

    //显示
    public void display() {
        System.out.println("网易天气: " + "温度 = " +
                temperature + ", 湿度 = " + humidity + ", 气压 = " + pressure);
    }
}

测试

public static void main(String[] args) {
        Observer currentConditions = new CurrentConditions();
        Observer wangyi=new Wangyitianqi();
        WeatherData weatherData=new WeatherData();

        weatherData.registObserver(currentConditions);//注册实时天气
   		 weatherData.registObserver(wangyi);		//注册网易天气
        weatherData.setData(10.0f,20.0f,2f);
        System.out.println("============更新天气===========");
        weatherData.setData(0.1f,0,0);
    }

在这里插入图片描述

三、Java 内置观察者模式

3.1 了解 Java 内置观察者模式

java.util 包内 包含最基本的Observable 类与 Observer 接口,这和上面的 Subject 接口与 Observer 接口很类似。Observable 类与 Observer 接口使用起来更方便,因为许多的功能已经提供了。

3.2 Java 内置观察者模式如何运作

(1)如何把对象定义为观察者?

实现观察者 (Observer) 接口,调用任何 Observable 对象的 addObserve() 方法。当不想要当观察者时,调用 deleteObserve() 方法。

(2)可观察者如何发送通知?

  1. 先调用 setChanged() 方法,标记状态已经被改变的事实。
  2. 调用 notifyObservers() 或 notifyObservers(Object arg) 方法。

(3)观察者如何接收通知?

同以前一样,观察者实现了 update(Observable o, Object arg) 方法,只是方法签名不太一样。
在这里插入图片描述
发布者
在这里插入图片描述
在这里插入图片描述
和之前实现的方法一样
在这里插入图片描述

转自https://blog.csdn.net/codejas/article/details/79106018

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值