同步 EDA 框架设计

一 点睛

1 Message

在基于 Message 的系统中,每一个 Event 也可以被称为 Message,Message 是对 Event 更高一个层级的抽象,每一个 Message 都有一个特定的 Type 用于与对应的 Handler 做关联。它是一种数据。

2 Chanel

Change 用于接收来自 Event Loop 分配的消息,每一个 Channel 负责处理一种类型的消息。它是对数据的处理。

3 DynamicRouter

它的作用类似于 Event Loop,其主要是帮助 Event 找到合适的 Channel 并且传送给它,它是连接 Event 和 Channel 之间的桥梁。

4 Event

Event 是对 Message 的一个最简单的实现,在后续使用过程中,将 Event 直接作为其他 Message 的基类使用。

5 EventDispatcher

EventDispatcher 是对 DynamicRouter 一个最基本的实现,适合在单线程的情况下进行使用,因此不需要考虑线程安全问题。

6 测试类

连接上述各组件,完成测试。

二 代码

1 Message

package synceda;

public interface Message {
    // 返回 Message 的类型
    Class<? extends Message> getType();
}

2 Chanel

package synceda;

public interface Channel<E extends Message> {
    // 用于负责 Message 的调度
    void dispatch(E message);
}

3 DynamicRouter

package synceda;

public interface DynamicRouter<E extends Message> {
    // 针对每一种 Message 类型注册相关的 Channel,只有找到合适的 Channel 该 Message 才会被处理
    void registerChannel(Class<? extends E> messageType, Channel<? extends E> channel);

    // 为相应的 Channel 分配 Message
    void dispatch(E message);
}

4 Event

package synceda;

public class Event implements Message {
    @Override
    public Class<? extends Message> getType() {
        return getClass();
    }
}

5 EventDispatcher

package synceda;

import java.util.HashMap;
import java.util.Map;

/**
 * @className: EventDispatcher
 * @description: 该类不是一个线程安全的类
 * @date: 2022/5/18
 * @author: cakin
 */
public class EventDispatcher implements DynamicRouter<Message>{
    // 用于保存 Channel 和 Message 的关系
    private final Map<Class<? extends Message>,Channel> routerTable;

    public EventDispatcher() {
        this.routerTable = new HashMap<>();
    }

    @Override
    public void registerChannel(Class<? extends Message> messageType, Channel<? extends Message> channel) {
        this.routerTable.put(messageType,channel);
    }

    @Override
    public void dispatch(Message message) {
        if(routerTable.containsKey(message.getType())){
            // 直接获取对应的 Channel 处理 Message
            routerTable.get(message.getType()).dispatch(message);
        } else {
            throw new MessageMatcherException("can not match thw channel for ["+message.getType()+"] type");
        }
    }
}

6 异常类

package synceda;

public class MessageMatcherException extends RuntimeException {
    public MessageMatcherException(String message) {
        super(message);
    }
}

7 测试类

package synceda;

public class EventDispatcherExample {
    // InputEvent 中定义了两个属性 X 和 Y,主要用于其他 Channel 中的元素
    static 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;
        }
    }

    // 用于存放结果的 Event
    static class ResultEvent extends Event {
        private final int result;

        public ResultEvent(int result) {
            this.result = result;
        }

        public int getResult() {
            return result;
        }
    }

    // 处理 ResultEvent 的 Handler(Channel),只是简单地将计算结果输出到控制台
    static class ResultEventHandler implements Channel<ResultEvent> {

        @Override
        public void dispatch(ResultEvent message) {
            System.out.println("The result is:" + message.getResult());
        }
    }

    // InputEventHandler 需要向 Router 发送 Event,因此在构造的时候需要传入 Dispatcher
    static class InputEventHandler implements Channel<InputEvent> {
        private final EventDispatcher dispatcher;

        public InputEventHandler(EventDispatcher dispatcher) {
            this.dispatcher = dispatcher;
        }

        // 将计算的结果构造成新的 Event 提交给 Router
        @Override
        public void dispatch(InputEvent message) {
            System.out.printf("X:%d,Y:%d\n", message.getX(), message.getY());
            int result = message.getX() + message.getY();
            dispatcher.dispatch(new ResultEvent(result));
        }

        public static void main(String[] args) {
            EventDispatcher dispatcher = new EventDispatcher();
            // 将 Event 和 Handler(Channel)的绑定关系注册到 DisPatcher
            dispatcher.registerChannel(InputEvent.class, new InputEventHandler(dispatcher));
            dispatcher.registerChannel(ResultEvent.class, new ResultEventHandler());
            dispatcher.dispatch(new InputEvent(1, 2));
        }
    }
}

三 测试结果

X:1,Y:2

The result is:3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值