引言
观察者(Observer)模式
又名发布-订阅(Publish/Subscribe)模式,是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个 “观察” 该对象的其他对象。
文章目录
一、引子:观察者模式解决怎么样的问题、怎么解决
现在我们碰到一个实际问题描述如下
假如你有两种类型的对象:
顾客
和商店
。顾客对某个特定品牌的产品非常感兴趣, 而该产品很快将会在商店里出售顾客可以每天来商店看看产品是否到货。但如果商品尚未到货时,绝大多数来到商店的顾客都会空手而归
另一方面,每次新产品到货时,商店可以向所有顾客发送邮件 (可能会被视为垃圾邮件)。 这样,部分顾客就无需反复前往商店了,但也可能会惹恼对新产品没有兴趣的其他顾客
🤖 Q:我们似乎遇到了一个矛盾: 要么让顾客浪费时间检查产品是否到货, 要么让商店浪费资源去通知没有需求的顾客
A:使用观察者模式来解决这个问题,首先需要了解一下发布者与订阅者的概念,了解基础的Observer模式怎么运行,然后再来解决这个问题
拥有一些值得关注的状态的对象通常被称为目标,由于它要将自身的状态改变通知给其他对象, 我们也将其称为发布者publisher
。所有希望关注发布者状态变化的其他对象被称为订阅者subscribers
回到上述问题
- publisher -> 超市
- subscribers -> 顾客
观察者模式建议你为发布者类添加订阅机制,让每个对象都能订阅或取消订阅发布者事件流
这并不像听上去那么复杂。实际上,我们用一张图就可以将观察者模式搞明白
二、一张图说明观察者模式的结构
可以看到图中有 publisher / subscriber / client 三个角色,他们各司其职,而观察者模式常用的几个角色无非以下几种
- 基础发布者接口
- 具体发布者实现类
- 通用订阅者接口
- 具体订阅者实现类,实现响应等操作
对于发布者而言
-
发布者一个用于存储订阅者对象引用的列表成员变量
ArrayList<> subscribers = new ArrayList<>();
-
几个用于添加或删除该列表中订阅者的公有方法
public boolean addSubscriber(subscriber); public boolean removeSubscriber(subscriber);
-
通知更新
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