原理
通过事件对象的dispatch方法进行事件传递
源码路径
代码
1. 事件定义
1. 1 事件接口(Message)
public interface Message {
/**
* 返回消息类型
* @return
*/
Class<? extends Message> getType();
}
1.2 事件基类(Event)
public class Event implements Message {
@Override
public Class<? extends Message> getType() {
return getClass();
}
}
1.3 事件实现
1.3.1 InputEvent
public class ResultEvent extends Event {
private final String result;
public ResultEvent(String result) {
this.result = result;
}
public String getResult() {
return result;
}
}
1.3.2 FormatEvent
public class FormatEvent extends Event {
private int result;
public FormatEvent(int result) {
this.result = result;
}
public int getResult() {
return result;
}
}
1.3.3 ResultEvent
public class ResultEvent extends Event {
private final String result;
public ResultEvent(String result) {
this.result = result;
}
public String getResult() {
return result;
}
}
2. 事件处理器
2.1 Channel
dispatch为核心方法,事件通过该方法进行传播
public interface Channel<E extends Message> {
/**
* 调度消息
*
* @param message
*/
void dispatch(E message);
}
2.2 InputEventHandler
输入事件处理器,每个处理器注入一个事件转发器对象,帮助进行事件转发
public class InputEventHandler implements Channel<InputEvent> {
private final EventDispatcher resultDispatcher;
public InputEventHandler(EventDispatcher resultDispatcher) {
this.resultDispatcher = resultDispatcher;
}
@Override
public void dispatch(InputEvent message) {
// 输入后进行计算
int result = message.getX() + message.getY();
System.out.printf("input结果:%d\n", result);
// 将消息交给结果处理器
resultDispatcher.dispatch(new FormatEvent(result));
}
}
2.3 FormatEventHandle
格式化事件处理器
public class FormatEventHandler implements Channel<FormatEvent> {
private final EventDispatcher dispatcher;
public FormatEventHandler(EventDispatcher dispatcher) {
this.dispatcher = dispatcher;
}
@Override
public void dispatch(FormatEvent message) {
int result = message.getResult();
String resultFormat = String.format("【格式化】标准输出结果为: %d", result);
System.out.printf("format结果:%s\n", resultFormat);
this.dispatcher.dispatch(new ResultEvent(resultFormat));
}
}
2.4 ResultEventHandler
结果输出事件处理器
public class ResultEventHandler implements Channel<ResultEvent> {
@Override
public void dispatch(ResultEvent message) {
System.out.format("result结果: %s\n", message.getResult());
}
}
3. 事件转发器
3.1 转发器接口(DynamicRouter)
public interface DynamicRouter<E extends Message> {
/**
* 每种类型的消息注册一个通道
*
* @param messageType
* @param channel
*/
void registerChannel(Class<? extends E> messageType, Channel<? extends E> channel);
/**
* 调度:为Channel分配Message
*
* @param message
*/
void dispatch(E message);
}
3.2 转发器实现(EventDispatcher)
routerTable中存放注册的消息处理器,转发时候根据消息类型使用对应的处理器进行处理
public class EventDispatcher implements DynamicRouter<Event> {
private final Map<Class<? extends Message>, Channel> routerTable;
public EventDispatcher() {
this.routerTable = new ConcurrentHashMap<>();
}
@Override
public void registerChannel(Class<? extends Event> messageType, Channel<? extends Event> channel) {
this.routerTable.put(messageType, channel);
}
/**
* 分发: 根据Event的类型获取对应的处理器(Channel)。如: InputEvent--> InputEventHandler, resultEvent --> ResultEventHandler
* @param message
*/
@Override
public void dispatch(Event message) {
if (this.routerTable.containsKey(message.getType())) {
System.out.format("事件转发: %s\n", message.getType().getSimpleName());
routerTable.get(message.getType()).dispatch(message);
} else {
throw new RuntimeException(String.format("该类型的消息未注册:%s", message.getType()));
}
}
}
4. 调用
将输入事件、格式化事件、输出事件依次注册到EventDispatcher上
public class EventDispatcherTest {
public static void main(String[] args) {
EventDispatcher dispatcher = new EventDispatcher();
// 注册事件(Event)对应的处理器: InputEvent --> InputEventHandler, ResultEvent --> ResultEventHandler
dispatcher.registerChannel(InputEvent.class, new InputEventHandler(dispatcher));
// 格式化数据事件
dispatcher.registerChannel(FormatEvent.class, new FormatEventHandler(dispatcher));
// ResultEventHandler为最后一个结果,不再需要dispatcher进行转发了
dispatcher.registerChannel(ResultEvent.class, new ResultEventHandler());
dispatcher.dispatch(new InputEvent(2, 5));
}
}
5. 输出结果
事件转发: InputEvent
input结果:7
事件转发: FormatEvent
format结果:【格式化】标准输出结果为: 7
事件转发: ResultEvent
result结果: 【格式化】标准输出结果为: 7