深究设计模式之-观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,其主要目的是定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象状态发生变化时,所有依赖于它的观察者都得到通知并被自动更新。观察者模式使得主题对象和观察者对象之间保持松耦合,以便可以灵活地扩展和重用。

在观察者模式中发生改变的对象称为观察目标 ,而被通知的对象称为观察者,一个观察目标可以应对多个观察者,而且这些观察者之间可以没有任何相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展.

比如我们生活中的等待红绿灯的汽车,红绿灯就是一个观察目标,而所有等待的汽车就是观察者。

主要角色:

  1. 主题(Subject): 也就是抽象的被观察者,负责维护一系列观察者对象,并通知它们状态的变化。

  2. 具体主题(Concrete Subject): 也就是具体的被观察者对象,实现了主题接口,负责状态的存储和变化,当状态发生变化时通知观察者。

  3. 观察者(Observer): 定义了一个更新接口,用于接收主题对象的通知。

  4. 具体观察者(Concrete Observer): 实现了观察者接口,当接收到主题对象的通知时进行相应的更新操作。

示例:

一个气象站的例子,气象站可以实时测量温度、湿度和气压,并通知观察者(如手机、电视等设备)。

java 复制代码
package com.luke.designpatterns.observerPattern;

import java.util.ArrayList;
import java.util.List;

// 抽象的被观察者
interface Subject {
    void addObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// 具体的被观察者 - 气象站
class WeatherStation implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherStation() {
        this.observers = new ArrayList<>();
    }

    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        notifyObservers();
    }

    @Override
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(temperature, humidity, pressure);
        }
    }
}

// 抽象的观察者
interface Observer {
    void update(float temperature, float humidity, float pressure);
}

// 具体观察者 - 手机
class PhoneDisplay implements Observer {
    @Override
    public void update(float temperature, float humidity, float pressure) {
        System.out.println("Phone Display: Temperature - " + temperature + "°C, Humidity - " + humidity + "%");
    }
}

// 具体观察者 - 电视
class TVDisplay implements Observer {
    @Override
    public void update(float temperature, float humidity, float pressure) {
        System.out.println("TV Display: Pressure - " + pressure + "hPa");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        // 创建被观察者
        WeatherStation weatherStation = new WeatherStation();

        // 添加观察者
        Observer phoneDisplay = new PhoneDisplay();
        Observer tvDisplay = new TVDisplay();
        
        weatherStation.addObserver(phoneDisplay);
        weatherStation.addObserver(tvDisplay);

        // 模拟气象站测量并通知观察者
        weatherStation.setMeasurements(25.5f, 60.0f, 1012.5f);
    }
}

在这个例子中,WeatherStation 是具体的被观察者,负责测量气象信息并通知观察者。Observer 是观察者接口,定义了更新方法。PhoneDisplayTVDisplay 是具体观察者,实现了更新方法,并在接收到通知时进行相应的操作。

客户端代码创建了一个气象站作为主题,添加了手机和电视作为观察者。当气象信息发生变化时,主题通知观察者进行更新。观察者模式使得主题和观察者之间的关系变得灵活,可以方便地增加、删除观察者,同时确保主题对象不需要知道观察者的具体细节。

适用场景

观察者模式适用于以下场景:

  1. 对象间存在一对多的依赖关系: 当一个对象的变化需要通知多个其他对象时,观察者模式非常有用,因为它建立了一种松散耦合的关系。

比如图形界面中的事件处理。考虑一个按钮对象作为被观察者,而多个UI组件(比如文本框、复选框等)作为观察者。当按钮被点击时,所有注册的UI组件都能够接收到通知并执行相应的操作。

  1. 抽象模型有两个方面,其中一个依赖于另一方面: 当一个对象的状态变化需要影响到另一个对象,但又希望保持独立性时,可以考虑使用观察者模式。

比如股票市场。股票价格作为被观察者,而图表和报价服务作为观察者。当股票价格变化时,图表和报价服务能够接收到通知并更新显示的数据。

  1. 系统需要分布式事件处理: 观察者模式在实现分布式事件处理系统时很有用,因为它允许对象之间通过事件通知进行通信,而无需直接了解彼此的存在。

比如在线协作编辑器。文档的变化作为被观察者,而不同用户的编辑器作为观察者。通过观察者模式,文档的变化可以实时地通知到所有其他用户的编辑器,实现协同编辑功能。

  1. 动态更新情况: 当一个对象的改变需要动态地通知其他对象,并且不希望知道具体通知哪些对象时,观察者模式提供了一种灵活的解决方案。

比如一个天气应用程序。天气数据作为被观察者,而不同的天气组件(比如温度显示、风速显示等)作为观察者。当天气数据发生变化时,所有注册的天气组件都能够动态更新显示最新的天气信息。

总体来说,观察者模式适用于需要解耦对象之间依赖关系、实现松散耦合、并提供灵活性和可扩展性的情况。

相关推荐
你在我身后2 分钟前
Spring-JAVA
java·后端·spring
卓越软件开发1 小时前
Java计算机毕业设计基于SSM宠物美容信息管理系统数据库源代码+LW文档+开题报告+答辩稿+部署教程+代码讲解
java·课程设计·宠物
丁总学Java1 小时前
Cannot deserialize instance of java.lang.String out of START_ARRAY token
java·windows·python
+7201 小时前
Java 的 HttpClient 中使用 POST 请求传递参数
java·开发语言
lozhyf2 小时前
如何使用Spring boot框架实现图书管理系统
java·spring
WalkingWithTheWind~3 小时前
Linux搭建Nginx直播流媒体服务RTMP/RTSP转Http-flv视频浏览器在线播放/Vue/Java/ffmpeg
java·linux·nginx·ffmpeg·vue·http-flv·rtsp
FLZJ_KL3 小时前
【设计模式】【创建型模式】抽象工厂模式(Abstract Factory)
java·设计模式·抽象工厂模式
攻城狮7号3 小时前
【第四节】C++设计模式(创建型模式)-Builder(建造者)模式
c++·设计模式·建造者模式
Nita.3 小时前
设计模式| 观察者模式 Observer Pattern详解
观察者模式·设计模式·c#