观察者模式 - Java实现
观察者模式
定义
在对象之间定义了一对多的依赖, 这样一来, 当一个对象改变状态, 依赖他的对象会收到通知并自动更新. (自己传播出去)
其实就是发布订阅模式, 发布者发布信息, 订阅者获取信息, 订阅了就能收到信息, 没订阅就收不到信息.
通俗解释
订阅: 订阅者告诉发布者, 我是谁, 有新消息了你应该怎么告诉我 (也就是持有订阅对象, 可调用订阅者接收消息的方法)
发布: 调用订阅者接收消息的接口, 向自己所有的订阅者推送消息
发布者必须具备的接口:
订阅, 取消订阅, 推送消息
订阅者必须具备的接口
如何接收消息
模式结构图
在上图的结构中, Observer作为观察者, Observable则作为被观察者, Observable的状态改变会给注册的 Observer进行通知, 考虑易用和低耦合, 保证高度地协作.
代码演示
package com.bobo.interview.designPattern;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* @author: bobo [bojan@91fifa.com]
* @date: 2020-04-24 15:36
* @desc: 观察者模式
*/
public class ObserverPattern {
public static void main(String[] args) {
WeChatServer weChatServer = new WeChatServer();
User u1 = new User("张三");
User u2 = new User("李四");
weChatServer.registerObserver(u1);
weChatServer.registerObserver(u2);
weChatServer.setInformation("你好呀!");
weChatServer.removeObserver(u2);
weChatServer.setInformation("发红包喽! ");
}
}
/**
* 定义一个抽象被观察者接口, 需要提供 订阅, 取消订阅, 推送消息3个方法
*/
interface Observable {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObserve();
}
/**
* 定义一个抽象观察者接口, 需要暴露 接收消息的方法
*/
interface Observer {
void update(String message);
}
/**
* 定义具体的被观察者
*/
@Data
class WeChatServer implements Observable {
private List<Observer> list;
private String message;
public WeChatServer() {
list = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
if (!list.contains(observer)) {
list.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if (!list.isEmpty()) {
list.remove(observer);
}
}
@Override
public void notifyObserve() {
for (Observer observer : list) {
observer.update(message);
}
}
public void setInformation(String s) {
this.message = s;
System.out.println(" —— —— —— —— —— 微信服务更新消息: " + s );
// 消息更新, 通知所有观察者
notifyObserve();
}
}
// 定义具体观察者
@Data
class User implements Observer {
private String name;
private String message;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
this.message = message;
read();
}
public void read() {
System.out.println(name + " 收到消息: " + message);
}
}
执行结果如下