引言
观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象
听起来很抽象,不着急,我们来通过一个例子去理解它
案例,发送消息
需求说明
我现在需要实现一个简单的功能,就是每当用户点击我的头像后,被点击人就会收到一个通知
角色
注册编辑者(Editor)、事件管理者(EventManager)、观察者(InformationListener)、调用者(Client)
代码
我先理清一下下面代码的思路,以方便你阅读代码
Editor:注册者,这个就是管理事件的大管家,当然要触发什么事件要先在这里注册(实际上是将注册的 内容存放到一个map中)
EventListener:事件监听接口,以便后期开发不同的监听者类
EventType:事件类型枚举类
InformationListener:事件监听接口的实现类
MessagePush:监听到对应的事件类型后,就执行的动作,可以自行更改
Client:客户端,相当于调用者或者是Controller
Editor
public class Editor {
private String content;
public EventManager manager;
public Editor(){
this.manager = new EventManager(EventType.SUPPORT.getValue(),EventType.COMMENT.getValue(),EventType.OFFICIAL_NOTIFICATION.getValue());
}
public void trigger(EventType eventType,String content){
this.content = content;
manager.notify(eventType,content);
}
}
EventManager
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class EventManager {
Map<String, List<EventListener>> listeners = new HashMap<>();
/**
* 先把监听者初始化一下,存放一些监控操作以及对应得空集合,以后执行对应得操作得时候再存储内容到集合中
* @param operations 监控得操作
*/
public EventManager(String... operations){
for (String operation : operations) {
listeners.put(operation,new ArrayList<>());
}
}
public void registerEvent(EventType eventType, EventListener listener){
listeners.get(eventType.getValue()).add(listener);
}
public void removeEvent(String eventType,EventListener listener){
listeners.get(eventType).remove(listener);
}
public void notify(EventType eventType,String content){
List<EventListener> eventListeners = listeners.get(eventType.getValue());
eventListeners.forEach(eventListener -> eventListener.update(eventType,content));
}
}
EventListener
public interface EventListener {
/**
* @param eventType 事件类型,这里只有点赞或者评论
* @param content 事件内容
*/
void update(EventType eventType, String content);
}
InformationListener
public class InformationListener implements EventListener {
private String operationUserId;
private String beOperatedUserId;
private MessagePush messagePush = new MessagePush();
public InformationListener(String operationUserId, String beOperatedUserId) {
this.operationUserId = operationUserId;
this.beOperatedUserId = beOperatedUserId;
}
/**
* 此处就采取保存
*
* @param eventType 事件类型,这里只有点赞或者评论
* @param content 事件内容
*/
@Override
public void
update(EventType eventType, String content) {
if (EventType.SUPPORT.getValue().equals(eventType.getValue())) {
//点赞操作
System.out.println("点赞");
System.out.println("用户" + operationUserId + ",对用户" + beOperatedUserId + "发生了" + eventType + "事件,内容是" + content);
messagePush.push(this.operationUserId, this.beOperatedUserId);
} else if (EventType.COMMENT.getValue().equals(eventType.getValue())) {
//评论操作
System.out.println("评论");
messagePush.push(this.operationUserId, this.beOperatedUserId);
System.out.println("用户" + operationUserId + ",对用户" + beOperatedUserId + "发生了" + eventType + "事件,内容是" + content);
}else if(EventType.OFFICIAL_NOTIFICATION.getValue().equals(eventType.getValue())){
//官方通知
System.out.println("官方通知");
messagePush.push(this.operationUserId,this.beOperatedUserId);
System.out.println("用户" + operationUserId + ",对用户" + beOperatedUserId + "发生了" + eventType + "事件,内容是" + content);
}
}
}
枚举类EventType
public enum EventType {
SUPPORT("support"), COMMENT("comment"),
OFFICIAL_NOTIFICATION(" official notification");
private String value;
public String getValue() {
return value;
}
EventType(String value) {
this.value = value;
}
}
Client
import java.util.UUID;
public class Client {
public static void main(String[] args) {
Editor editor = new Editor();
editor.manager.registerEvent(EventType.SUPPORT,
new InformationListener(UUID.randomUUID().toString(),UUID.randomUUID().toString()));
editor.manager.registerEvent(EventType.COMMENT,
new InformationListener(UUID.randomUUID().toString(),UUID.randomUUID().toString()));
editor.manager.registerEvent(EventType.OFFICIAL_NOTIFICATION,
new InformationListener(UUID.randomUUID().toString(),UUID.randomUUID().toString()));
editor.trigger(EventType.SUPPORT,"点赞1");
editor.trigger(EventType.COMMENT,"你的文章真好");
editor.trigger(EventType.OFFICIAL_NOTIFICATION,"你被通缉了");
}
}
MessagePush
public class MessagePush {
public void push(String operationUserId,String beOperatedUserID){
System.out.println(operationUserId + "," + beOperatedUserID);
}
}
如果你认真的看到这里就应该对观察者模式大概有了了解,这个作为一种行为模式,本质上就是对一种行为的监听然后执行对应的动作而已
在客户端我们已经注册了三个动作,点赞,评论,官方通知,所以我们就得到了以下结果
结束语
这只是一种写法例子,实际开发中我们肯定还是需要更改一些地方,比如客户端是哪里或者具体监听执行什么动作都是需要因情况而改变