设计模式---观察者模式

  1.观察者模式是什么?

        Java的观察者模式是一种设计模式,它属于行为型设计模式家族,用于处理软件系统中对象之间的联动或者说事件通知机制。在观察者模式中,存在两个核心角色:观察者(Observer)和被观察者(Observable)。这种模式定义了对象之间的一对多依赖关系,允许一个对象(被观察者)的状态变化自动通知其他对象(观察者),从而这些对象可以做出相应的行为。

        以前记得都是自己写观察者注册、被观察者通知等操作,现在jdk将被观察者抽象出来了,只需要在业务变化中,调用抽象类的通知方法和数据已改变标识即可,观察者实现update方法即可。

 2.观察者的实现

具体到Java语言中的实现:

  1. 抽象被观察者(Observable)

    • Java提供了内置的java.util.Observable类作为抽象被观察者角色,它维护了一个观察者列表,并提供了添加、删除观察者以及通知所有观察者的方法。
  2. 具体被观察者(Concrete Observable)

    • 这是一个继承自Observable的类,通常会包含一些业务逻辑,当其内部状态发生变化时,调用setChanged()方法标记状态已更改,并通过调用notifyObservers(Object arg)来通知所有注册的观察者。
  3. 抽象观察者(Observer)

    • Java定义了java.util.Observer接口作为抽象观察者角色,接口中定义了update(Observable o, Object arg)方法,这是观察者接收到通知时需要实现的更新逻辑。
  4. 具体观察者(ConcreteObserver)

    • 实现了Observer接口的类,它们关注并响应被观察者的特定状态变化。当被观察者调用notifyObservers()时,所有具体观察者的update()方法会被调用,此时观察者可以根据传递的信息更新自己的状态。

这样设计的好处在于降低了对象之间的耦合度,使得系统更易于扩展和维护,同时能够实现实时的数据同步和状态更新。在GUI编程、事件驱动框架、MVC架构等场景中,观察者模式得到了广泛的应用。

3.代码示例

        示例代码以天气数据为例,各个不同功能的观察者根据天气数据做出不同的反应,天气数据改变后,通知观察者。

被观察者实现:


/**
 * 被观察者,天气
 */
public class WeatherData extends java.util.Observable {

    /**
     * 温度
     */
    private float temperature;

    /**
     * 湿度
     */
    private float humidity;


    /**
     * 大气压
     */
    private float pressure;


    /**
     * 设置业务数据,并通知观察者
     * @param temperature
     * @param humidity
     * @param pressure
     */
    public void setData(float temperature,float humidity,float pressure){

        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        this.setChanged();
        this.notifyObservers();
    }


    public float getTemperature() {
        return temperature;
    }

    public float getHumidity() {
        return humidity;
    }

    public float getPressure() {
        return pressure;
    }
}

观察者1的示例:

import com.zhangzz.WeatherData;

import java.util.Observable;
import java.util.Observer;

/**
 * 气温观察者
 */
public class TemperatureObServer implements Observer{

    /**
     * 温度
     */
    private float temperature;

    /**
     * 湿度
     */
    private float humidity;

    
    public void display() {
        System.out.println("当前温度:" + temperature + "°C, 湿度:" + humidity + "%");
    }

    @Override
    public void update(Observable o, Object arg) {
        if(o instanceof WeatherData){
            WeatherData data = (WeatherData)o;
            this.humidity = data.getHumidity();
            this.temperature = data.getTemperature();
            display();
        }
    }
}

观察者2的示例:

import com.zhangzz.WeatherData;

import java.util.Observable;
import java.util.Observer;

/**
 * 具体观察者2:预报数据显示
 */
public class ForecastObServer implements Observer{

    /**
     * 大气压
     */
    private float currentPressure = 29.92f; // 假设初始气压值

  

    @Override
    public void update(Observable o, Object arg) {
        //通过该方式,可以观察多个被观察者,实现一对多的依赖。
        if(o instanceof WeatherData){
            WeatherData weatherData = (WeatherData) o;
            float newPressure = weatherData.getPressure();
            if (newPressure > currentPressure) {
                System.out.println("明天可能是晴天");
            } else if (newPressure < currentPressure) {
                System.out.println("明天可能会下雨");
            } else {
                System.out.println("天气稳定");
            }
            currentPressure = newPressure;
            
        }
    }
}

测试代码:

import com.zhangzz.observer.ForecastObServer;
import com.zhangzz.observer.TemperatureObServer;

public class Test {

    public static void main(String[] args) {
        //实例化天气
        WeatherData data = new WeatherData();

        //实例化预报实例
        ForecastObServer forecastObServer = new ForecastObServer();
        //实例化气温实例
        TemperatureObServer temperatureObServer = new TemperatureObServer();

        //像被观察者注册实例
        data.addObserver(forecastObServer);
        data.addObserver(temperatureObServer);

        //修改气温数据
        data.setData(80, 65, 30.4f);
        data.setData(82, 70, 29.2f);
    }
}

执行结果:

当前温度:80.0°C, 湿度:65.0%
明天可能是晴天
当前温度:82.0°C, 湿度:70.0%
明天可能会下雨

良好的代码设计,可以为系统带来更大的成长空间。避免了屎山代码导致系统无法继续迭代升级的可能。

相关推荐

  1. 设计模式观察模式

    2024-01-27 22:54:01       39 阅读
  2. 设计模式观察模式

    2024-01-27 22:54:01       33 阅读
  3. 设计模式——观察模式

    2024-01-27 22:54:01       23 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-27 22:54:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-27 22:54:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-27 22:54:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-27 22:54:01       20 阅读

热门阅读

  1. cs2系统提升思路

    2024-01-27 22:54:01       37 阅读
  2. 从k8s当中学习go cli脚手架开发利器-cobra

    2024-01-27 22:54:01       33 阅读
  3. 一篇文章带你全面理解热更新技术

    2024-01-27 22:54:01       32 阅读
  4. Golang 垃圾回收

    2024-01-27 22:54:01       32 阅读
  5. js如何数组去重

    2024-01-27 22:54:01       37 阅读
  6. 抖音私信风车怎么做,详细的实现过程,附视频

    2024-01-27 22:54:01       41 阅读
  7. Vue3使用百度地图marker点位实现水波纹动效

    2024-01-27 22:54:01       29 阅读