Java设计模式之观察者模式

本文深入探讨了观察者模式,解决如何在对象事件发生时通知多个观察对象的问题。通过一个商店与顾客的例子,展示了如何利用观察者模式避免顾客频繁检查商品到货情况或商店发送大量无效邮件。文章通过Java代码示例解释了基础发布者、具体发布者、通用订阅者接口和具体订阅者的实现,并讨论了观察者模式在Java源码中的应用及其适合的场景。此外,还比较了观察者模式与其他设计模式的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

观察者(Observer)模式 又名发布-订阅(Publish/Subscribe)模式,是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个 “观察” 该对象的其他对象。

image-20220531230616909

一、引子:观察者模式解决怎么样的问题、怎么解决

现在我们碰到一个实际问题描述如下

假如你有两种类型的对象:顾客商店。顾客对某个特定品牌的产品非常感兴趣, 而该产品很快将会在商店里出售

顾客可以每天来商店看看产品是否到货。但如果商品尚未到货时,绝大多数来到商店的顾客都会空手而归

另一方面,每次新产品到货时,商店可以向所有顾客发送邮件 (可能会被视为垃圾邮件)。 这样,部分顾客就无需反复前往商店了,但也可能会惹恼对新产品没有兴趣的其他顾客

🤖 Q:我们似乎遇到了一个矛盾: 要么让顾客浪费时间检查产品是否到货, 要么让商店浪费资源去通知没有需求的顾客

A:使用观察者模式来解决这个问题,首先需要了解一下发布者与订阅者的概念,了解基础的Observer模式怎么运行,然后再来解决这个问题

拥有一些值得关注的状态的对象通常被称为目标,由于它要将自身的状态改变通知给其他对象, 我们也将其称为发布者publisher。所有希望关注发布者状态变化的其他对象被称为订阅者subscribers

回到上述问题

  • publisher -> 超市
  • subscribers -> 顾客

观察者模式建议你为发布者类添加订阅机制,让每个对象都能订阅或取消订阅发布者事件流

这并不像听上去那么复杂。实际上,我们用一张图就可以将观察者模式搞明白

二、一张图说明观察者模式的结构

image-20220601001524508

图源

可以看到图中有 publisher / subscriber / client 三个角色,他们各司其职,而观察者模式常用的几个角色无非以下几种

  • 基础发布者接口
  • 具体发布者实现类
  • 通用订阅者接口
  • 具体订阅者实现类,实现响应等操作

对于发布者而言

  1. 发布者一个用于存储订阅者对象引用的列表成员变量

    ArrayList<> subscribers = new ArrayList<>();
    

    image-20220427010533450

  2. 几个用于添加或删除该列表中订阅者的公有方法

    public boolean addSubscriber(subscriber);
    public boolean removeSubscriber(subscriber);
    
  3. 通知更新

    for(s : subscribers){
         
         
    	s.update();
    }
    

对于订阅者接口

在绝大多数情况下,该接口仅包含一个update更新方法,该方法可以拥有多个参数,使发布能在更新时传递事件的详细信息。

public void update(context);

对于订阅者

  • 订阅者通常需要一些上下文信息来正确地处理更新,因此需要实现订阅者接口

  • 发布者通常会将一些上下文数据作为通知方法的参数进行传递。发布者也可将自身作为参数进行传递,使订阅者直接获取所需的数据

  • 订阅者可以对得到的数据做出一些响应

三、Java观察者模式代码示例

EventManager.java: 基础发布者

import EventSubscriber;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class EventManager {
   
   
    Map<String, List<EventSubscriber>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值