行为型模式之观察者模式
1. 简介
观察者模式(Observer Pattern)又叫发布订阅模式(Publish Subscription Pattern)。
观察者模式指的是多个对象间存在一对多的依赖关系, 当一个对象的状态发生改变时,所有依赖与它的对象都得到通知并自动更新。
发布者,是一对多对象关系中的1,负责管理和维护多个订阅者,当自身状态发生改变时,通知订阅者作相应的处理。
订阅者,是一对多对象关系中的多,负责当接收到发布者通知时作相应的处理。
2. 角色
Subject
- 抽象的发布者,负责定义发布者管理订阅者的相关方法。ConcreteSubject
- 实际的发布者,负责实现管理订阅者的相关方法,并实现当自身状态发生改变时,通知订阅者的相关逻辑。Observer
- 抽象订阅者,定义订阅者接收通知的规范方法。ConcreteObserver
- 实际订阅者,实现接收到通知如何处理的逻辑。
3. 代码演示
情景描述:
当前我们以两个微信用户关注公众号的场景去实现发布订阅者模式。
3.1 代码
package com.inconspicuousy.pattern.observer;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
// 公众号发布的文章类
@Getter
@Setter
@AllArgsConstructor
class Message {
private String content;
}
// 抽象的观察者: 微信用户
interface Observer {
// 对接收到的消息做出响应
void response(Message message);
}
// 抽象的发布者
interface Publisher {
// 添加观察者
void add(Observer observer);
// 删除观察者
void remove(Observer observer);
// 通知所有的观察者处理消息
void notifyObservers(Message message);
}
// 消息发布者
class ConcretePublisher implements Publisher {
private final List<Observer> observers = new ArrayList<>();
@Override
public void add(Observer observer) {
observers.add(observer);
}
@Override
public void remove(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(Message message) {
// 通知所有的接收者对消息做出响应
observers.forEach(observer -> observer.response(message));
}
}
// 实际的接收者
@EqualsAndHashCode
class ConcreteObserver implements Observer {
// 微信用户名
private final String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void response(Message message) {
System.out.println("当前" + name + "接收到的消息为" + message.getContent());
}
}
/**
* 观察者模式-发布订阅模式-代码示例
* @author peng.yi
*/
public class ObserverTest {
public static void main(String[] args) {
// 公众号A
Publisher concretePublisherA = new ConcretePublisher();
// 公众号B
Publisher concretePublisherB = new ConcretePublisher();
// 微信用户A
ConcreteObserver concreteObserverA = new ConcreteObserver("微信用户A");
// 微信用户B
ConcreteObserver concreteObserverB = new ConcreteObserver("微信用户B");
// 微信AB同时关注 公众号A
concretePublisherA.add(concreteObserverA);
concretePublisherA.add(concreteObserverB);
// 微信A关注公众号B
concretePublisherB.add(concreteObserverA);
// 公众号A发布文章
concretePublisherA.notifyObservers(new Message("我是公众号A发送的消息"));
// 公众号B发布文章
concretePublisherB.notifyObservers(new Message("我是公众号B发送的消息"));
System.out.println("===================微信用户A通知关注公众号A");
concretePublisherA.remove(concreteObserverA);
// 公众号A发布文章
concretePublisherA.notifyObservers(new Message("我是公众号A发送的消息"));
}
}
3.2 测试结果
当前微信用户A接收到的消息为我是公众号A发送的消息
当前微信用户B接收到的消息为我是公众号A发送的消息
当前微信用户A接收到的消息为我是公众号B发送的消息
===================微信用户A取消关注公众号A
当前微信用户B接收到的消息为我是公众号A发送的消息
Process finished with exit code 0