基于Event-Driven架构设计实现如下需求
* 1. 输入2个数 x 和 y, 并进行相加
* 2. 对1中的结果进行格式化
* 3. 将2中格式化的结果输出(打印)
使用Event-Driven架构进行设计,对于每一种消息类型分别定义 Event、Channel,进行差异化处理;
package com.hz.design.eventdriven.message;
/**
* @description: 消息接口
* @author: pp_lan
* @date: 2022/3/25
*/
public interface Message {
/**
* 返回消息类型
* @return
*/
Class extends Message> getType();
}
package com.hz.design.eventdriven.message;
/**
* @description: Event类型的消息
* @author: pp_lan
* @date: 2022/3/25
*/
public class Event implements Message {
@Override
public Class extends Message> getType() {
return getClass();
}
}
package com.hz.design.eventdriven.message;
/**
* @description:
* @author: pp_lan
* @date: 2022/3/25
*/
public class InputEvent extends Event {
private final int x;
private final int y;
public InputEvent(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
package com.hz.design.eventdriven.message;
/**
* @description: 格式化事件
* @author: pp_lan
* @date: 2022/3/25
*/
public class FormatEvent extends Event {
private int result;
public FormatEvent(int result) {
this.result = result;
}
public int getResult() {
return result;
}
}
package com.hz.design.eventdriven.message;
/**
* @description:
* @author: pp_lan
* @date: 2022/3/25
*/
public class ResultEvent extends Event {
private final String result;
public ResultEvent(String result) {
this.result = result;
}
public String getResult() {
return result;
}
}
package com.hz.design.eventdriven.router;
import com.hz.design.eventdriven.channel.Channel;
import com.hz.design.eventdriven.message.Message;
/**
* @description: 动态路由
* @author: pp_lan
* @date: 2022/3/25
*/
public interface DynamicRouter {
/**
* 每种类型的消息注册一个通道
*
* @param messageType
* @param channel
*/
void registerChannel(Class extends E> messageType, Channel extends E> channel);
/**
* 调度:为Channel分配Message
*
* @param message
*/
void dispatch(E message);
}
package com.hz.design.eventdriven.router;
import com.hz.design.eventdriven.channel.Channel;
import com.hz.design.eventdriven.message.Event;
import com.hz.design.eventdriven.message.Message;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @description: 调度器
* @author: pp_lan
* @date: 2022/3/25
*/
public class EventDispatcher implements DynamicRouter {
private final Map, 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()));
}
}
}
package com.hz.design.eventdriven.channel;
import com.hz.design.eventdriven.message.Message;
/**
* @description: 通道
* @author: pp_lan
* @date: 2022/3/25
*/
public interface Channel {
/**
* 调度消息
*
* @param message
*/
void dispatch(E message);
}
package com.hz.design.eventdriven.channel;
import com.hz.design.eventdriven.message.FormatEvent;
import com.hz.design.eventdriven.message.InputEvent;
import com.hz.design.eventdriven.message.ResultEvent;
import com.hz.design.eventdriven.router.EventDispatcher;
/**
* @description:
* @author: pp_lan
* @date: 2022/3/25
*/
public class InputEventHandler implements Channel {
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));
}
}
package com.hz.design.eventdriven.channel;
import com.hz.design.eventdriven.message.Event;
import com.hz.design.eventdriven.message.FormatEvent;
import com.hz.design.eventdriven.message.ResultEvent;
import com.hz.design.eventdriven.router.EventDispatcher;
/**
* @description:
* @author: pp_lan
* @date: 2022/3/25
*/
public class FormatEventHandler implements Channel {
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));
}
}
package com.hz.design.eventdriven.channel;
import com.hz.design.eventdriven.message.ResultEvent;
/**
* @description:
* @author: pp_lan
* @date: 2022/3/25
*/
public class ResultEventHandler implements Channel {
@Override
public void dispatch(ResultEvent message) {
System.out.format("result结果: %s\n", message.getResult());
}
}
package com.hz.design.eventdriven;
import com.hz.design.eventdriven.channel.FormatEventHandler;
import com.hz.design.eventdriven.channel.InputEventHandler;
import com.hz.design.eventdriven.channel.ResultEventHandler;
import com.hz.design.eventdriven.message.FormatEvent;
import com.hz.design.eventdriven.message.InputEvent;
import com.hz.design.eventdriven.message.ResultEvent;
import com.hz.design.eventdriven.router.EventDispatcher;
/**
* @description: 基于Event-Driven架构设计实现如下需求
* 1. 输入2个数 x 和 y, 并进行相加
* 2. 对1中的结果进行格式化
* 3. 将2中格式化的结果输出(打印)
* @author: pp_lan
* @date: 2022/3/25
*/
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));
}
}
Connected to the target VM, address: '127.0.0.1:62897', transport: 'socket'
事件转发: InputEvent
input结果:7
事件转发: FormatEvent
format结果:【格式化】标准输出结果为: 7
事件转发: ResultEvent
result结果: 【格式化】标准输出结果为: 7
Disconnected from the target VM, address: '127.0.0.1:62897', transport: 'socket'
参考:《JAVA高并发编程详解》-汪文君