详细讲解什么是观察者模式

简介: 详细讲解什么是观察者模式



       观察者模式是一种行为设计模式,它建立了一种对象之间的一对多依赖关系,使得当一个对象状态发生改变时,所有依赖它的对象都能得到通知并自动更新。这种模式常被用于实现分布式事件处理系统,消息通知系统等场景。本文将深入探讨观察者模式的原理、应用场景以及实现方式,旨在为读者提供全面的了解和应用观察者模式的指导。

观察者模式的核心概念

       观察者模式涉及两种主要角色:观察者被观察者。观察者是订阅了某个事件或主题的对象,而被观察者则是负责维护观察者列表并在状态改变时通知观察者的对象。

观察者

       观察者是系统中感兴趣事件的监听者。它们等待着被观察者发出的通知,并在接收到通知时执行相应的操作。观察者通常定义了一个接口,包含了在状态发生改变时需要执行的方法,以确保实现了观察者接口的类都能够响应事件。

被观察者

       被观察者是事件或主题的拥有者。它维护了一个观察者列表,并提供方法用于添加、移除和通知观察者。当被观察者的状态发生改变时,它会遍历观察者列表并调用每个观察者的相应方法,从而实现状态变化的通知。

观察者模式的应用场景

       观察者模式广泛应用于软件开发中,特别是在构建交互性强、解耦性好的系统时。以下是一些观察者模式的典型应用场景:

1. GUI 系统

       在图形用户界面(GUI)系统中,观察者模式常被用于处理用户界面组件之间的交互。例如,一个按钮的点击事件可以被多个监听器(观察者)捕获,从而执行不同的操作。

2. 事件驱动系统

       观察者模式在事件驱动系统中有着重要的应用,例如浏览器中的 DOM 事件。当页面上的元素发生交互时,注册的事件处理程序(观察者)会收到相应的通知,执行相应的操作。

3. 软件设计中的解耦

       观察者模式有助于降低系统中各组件之间的耦合度。被观察者和观察者之间的关系是松散的,使得系统更容易扩展和维护。

4. 消息通知系统

       观察者模式常被用于构建消息通知系统,其中订阅者是观察者,发布者是被观察者。当发布者发布新消息时,所有订阅者都能够接收到通知。

观察者模式的实现方式

       下面是一个简单的观察者模式的例子,假设我们有一个气象站,它可以实时测量温度,并通知多个观察者:

import java.util.ArrayList;
import java.util.List;
// 主题接口
interface Subject {
    void addObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}
// 观察者接口
interface Observer {
    void update(float temperature);
}
// 具体主题
class WeatherStation implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private float temperature;
    public void setTemperature(float temperature) {
        this.temperature = temperature;
        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);
        }
    }
}
// 具体观察者
class Display implements Observer {
    private float temperature;
    @Override
    public void update(float temperature) {
        this.temperature = temperature;
        display();
    }
    public void display() {
        System.out.println("Current Temperature: " + temperature);
    }
}
// 客户端
public class Client {
    public static void main(String[] args) {
        WeatherStation weatherStation = new WeatherStation();
        Display display1 = new Display();
        Display display2 = new Display();
        weatherStation.addObserver(display1);
        weatherStation.addObserver(display2);
        // 模拟温度变化
        weatherStation.setTemperature(25.5f);
        weatherStation.setTemperature(28.0f);
    }
}

       在这个例子中,WeatherStation 是具体主题,实现了 Subject 接口。Display 是具体观察者,实现了 Observer 接口。客户端通过调用 addObserver 方法将观察者注册到主题中,然后通过 setTemperature 方法模拟温度的变化,观察者会收到通知并更新自己的状态。

观察者模式的优缺点

优点:

  1. 解耦性强: 观察者模式可以使得观察者和被观察者之间解耦,观察者不需要知道被观察者的具体实现,只需关心事件通知即可。
  2. 扩展性好: 可以轻松地添加新的观察者,而不影响被观察者的实现,从而提高系统的可扩展性。
  3. 灵活性: 被观察者并不需要知道观察者的具体类型,可以观察任何实现了观察者接口的对象。

缺点:

  1. 通知顺序问题: 在某些情况下,观察者被通知的顺序可能是不确定的,这可能导致系统中的一些不一致性。如果观察者之间有相互依赖关系,通知的顺序就显得尤为重要。
  2. 可能引起性能问题: 当被观察者有大量观察者时,通知所有观察者可能导致性能问题。在某些情况下,采用异步通知的方式可能是一种解决方案,但也引入了复杂性。
  3. 数据同步问题: 如果观察者需要获取被观察者的状态信息,并且这些信息可能随时改变,那么观察者在处理通知时可能无法获取到一致的状态信息,导致数据同步问题。

结语

       观察者模式是一种强大的设计模式,它提供了一种简单而灵活的方式来实现对象之间的通信和协作。通过解耦被观察者和观察者,观察者模式使得系统更加灵活、可扩展,并促使良好的设计实践。然而,在使用观察者模式时需要注意通知顺序、性能问题和数据同步等方面的挑战,以确保系统的稳定性和可维护性。通过深入理解观察者模式的原理和实际应用,开发者可以更好地运用这一模式解决复杂的问题,提升系统的设计质量。

相关文章
|
存储 JSON 关系型数据库
Pandas载入txt、csv、Excel、JSON、数据库文件讲解及实战(超详细 附源码)
Pandas载入txt、csv、Excel、JSON、数据库文件讲解及实战(超详细 附源码)
491 0
|
11月前
|
JSON Go C语言
Go语言之定义结构体(Struct)-《Go语言实战指南》
Go 语言中的结构体(`struct`)是一种复合数据类型,可将多个不同类型的字段组合成一个类型。本文介绍了结构体的基本定义、实例创建方式、字段访问与修改、零值特性、比较规则、嵌套使用及标签功能。通过示例代码详细讲解了如何定义和操作结构体,以及其在 JSON 编码等场景的应用。
|
10月前
|
API 开发者
1688店铺订单接口指南攻略
1688店铺订单接口用于获取订单列表、查询订单详情及操作订单等。首先需注册为1688开放平台开发者,创建应用获取App Key与App Secret。使用API获取订单列表时,要申请订单查询权限,并通过HTTP请求传递参数(如seller_id、page、page_size和access_token)调用接口。此功能适用于管理1688店铺订单数据。
|
Java 关系型数据库 MySQL
体育赛事管理系统的设计与实现(源码+论文)_kaic
体育赛事管理系统的设计与实现(源码+论文)_kaic
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。
什么叫做 “面向对象” 编程?
本文介绍了面向对象编程(OOP)的概念、核心组件(类和对象)、三大特性(封装、继承和多态)以及六大设计原则,强调了面向对象编程在提高代码的可重用性、模块化、扩展性和维护性方面的优点。
1179 1
|
Android开发
基于Amlogic 安卓9.0, 驱动简说(三):使用misc框架,让驱动更简单
如何使用Amlogic T972安卓9.0系统上的misc框架来简化驱动程序开发,通过misc框架自动分配设备号并创建设备文件,从而减少代码量并避免设备号冲突。
316 0
基于Amlogic 安卓9.0, 驱动简说(三):使用misc框架,让驱动更简单
|
设计模式 API 数据库
【C/C++ 设计思路】C++中解耦策略的艺术:有效管理复杂依赖关系
【C/C++ 设计思路】C++中解耦策略的艺术:有效管理复杂依赖关系
924 3
|
JavaScript 前端开发 程序员
非专业程序员常用vscode插件
这里的vscode插件, 有四分之一你没用过, 这里的vscode设置, 80%你没设置过, 挖宝随缘
360 5
|
机器学习/深度学习 存储 算法
基于YOLOv8深度学习的农作物幼苗与杂草检测系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标检测
基于YOLOv8深度学习的农作物幼苗与杂草检测系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标检测

热门文章

最新文章