资讯专栏INFORMATION COLUMN

事件派发器模式

Yujiaao / 2078人阅读

摘要:在项目开发中,会遇到如下情形我们自己的服务订阅接收来自消息队列或者客户端的事件和请求,基于不同的事件采取对应的行动,这种情况下适合应用派发器模式。

在项目开发中,会遇到如下情形:我们自己的服务订阅、接收来自消息队列或者客户端的事件和请求,基于不同的事件采取对应的行动,这种情况下适合应用派发器模式。

主要模块

XXXEventDispatcher类
核心类,维护事件类型(EventType)到处理器(handler)的映射(存放在ConcurrentHashMap中);这个类在启动时,会通过XXXEventHandlerInitializer初始化这个map数据结构;在启动时,需要订阅或监听来自消息队列的事件;当对应的事件到达时,该类的dispatch方法会负责将事件分发到具体的处理器方法中进行处理。

package org.java.learn.java8.dispatcher;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2016/11/3
 * Time: 21:53
 */
@Component
public class XXXEventDispatcher implements AutoCloseable {
    @Resource
    private XXXEventHandlerInitializer initializer;

    private Map handlers = new ConcurrentHashMap<>();

    @PostConstruct
    public void init() {
        //建立绑定关系;
        initializer.init();
        //监听事件并派发
        dispatch("testMsg");
    }
    /**
     * 将XXX事件注册到派发器
     *
     * @param xxxEventType
     * @param xxxEventHandler
     */
    public void bind(XXXEventType xxxEventType, XXXEventHandler xxxEventHandler) {
        this.handlers.put(xxxEventType, ((eventType, context) -> {
            try {
                xxxEventHandler.handle(eventType, context);
            } catch (Exception e) {
                //记录错误日志
                e.printStackTrace();
            }
            //打印处理器执行日志
        }));
    }
    /**
     * 进行事件派发
     * @param eventMsg
     */
    private void dispatch(String eventMsg) {
        //(1) 从eventMsg中获取eventType;
        //(2) 根据eventMsg构造eventContext;
        //(3) 执行具体的处理器方法
    }

    public void close() throws Exception {
        //释放资源
    }
}

XXXEventHandlerInitializer类
这个类包括具体的业务处理方法,在系统初始化的时候,会将这些业务处理方法的方法引用注册到派发器中。

package org.java.learn.java8.dispatcher;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2016/11/3
 * Time: 21:56
 */
@Component
public class XXXEventHandlerInitializer {
    @Resource
    private XXXEventDispatcher dispatcher;

    public void init() {
        dispatcher.bind(XXXEventType.event1, this::handleProcess1);
        dispatcher.bind(XXXEventType.event2, this::handleProcess2);
        dispatcher.bind(XXXEventType.event3, this::handleProcess3);
    }
    
    private void handleProcess1(XXXEventType eventType, XXXEventContext context) {
        //事件1的处理逻辑
    }

    private void handleProcess2(XXXEventType eventType, XXXEventContext context) {
        //事件2的处理逻辑
    }

    private void handleProcess3(XXXEventType eventType, XXXEventContext context) {
        //事件3的处理逻辑
    }
}

XXXEventHandler:函数式接口
函数式接口是Java 8 中实现Lambda函数式编程的基础工具,思想就是要讲函数作为参数传递。如下图所示,这些方法引用都是该函数式接口的实现。


代码如下:

package org.java.learn.java8.dispatcher;
/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2016/11/3
 * Time: 22:03
 */
@FunctionalInterface
public interface XXXEventHandler {
    void handle(XXXEventType eventType, XXXEventContext context);
}

XXXEventContext类
这个类用于存储入参和返回值,具体情况可以灵活处理。

package org.java.learn.java8.dispatcher;
/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2016/11/3
 * Time: 22:04
 */
public class XXXEventContext {
    private int param1;
    private int param2;

    @Override
    public String toString() {
        return "XXXEventContext{" +
               "param1=" + param1 +
               ", param2=" + param2 +
               "}";
    }
}

XXXEventType枚举
这个类显然用于存储事件类型

package org.java.learn.java8.dispatcher;
/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2016/11/3
 * Time: 22:03
 */
public enum XXXEventType {
    event1,
    event2,
    event3
}

总结:在企业级开发中,有很多典型的应用场景和模式,事件派发器只是其中的一种,希望你也能够根据自己的实际情况加以应用。本文中提到的代码,参见我的github:LearnJava

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65283.html

相关文章

  • 【全栈React】第18天: Flux 简介

    摘要:在方法中处理数据有三不同的角色派发器储存视图层我们的组件的主要思想是有一个单一源储存他们只能通过触发更新。这些操作负责调用派发器可以订阅更改并相应地更新自己的数据。与不同不使用派发器而是使用纯函数来定义数据变异函数。 本文转载自:众成翻译译者:iOSDevLog链接:http://www.zcfy.cc/article/3812原文:https://www.fullstackreact...

    mtunique 评论0 收藏0
  • Dubbo 源码分析 - 服务调用过程

    摘要:服务调用过程比较复杂,包含众多步骤。源码分析在进行源码分析之前,我们先来通过一张图了解服务调用过程。服务调用方式支持同步和异步两种调用方式,其中异步调用还可细分为有返回值的异步调用和无返回值的异步调用。 注: 本系列文章已捐赠给 Dubbo 社区,你也可以在 Dubbo 官方文档中阅读本系列文章。 1. 简介 在前面的文章中,我们分析了 Dubbo SPI、服务导出与引入、以及集群容错...

    Travis 评论0 收藏0
  • clipboard.js代码分析(2)-emitter

    摘要:用于在同一主模块下的不同子模块以及不同主模块之间的通信,支持动态绑定作用域。如果用过的父子组件事件通信以及,对事件管理器应该不会陌生的。而且支持指定作用域,可以远程调用任意模块的函数。 上一篇文章介绍了clipboard.js这个工具库中的第一个依赖select这个工具库主要完成了对任意DOM元素的复制到粘贴板的功能。这次介绍一下clipboard.js源码中的第二个依赖的轻型工具库t...

    MoAir 评论0 收藏0
  • [翻译] 比较不同Observer模式的实现

    摘要:使用字符串定义事件类型,容易产生拼写错误并且自动完成不能很好的工作。消息和事件的目标之间并没有关系。通过命名规范来避免消息被错误的订阅者拦截。细粒度的控制每个监听器和事件类型。倾向于使用组合而不是继承。与大多数人使用的不同。 原文链接:Comparison between different Observer Pattern implementations 下面的比较只是关于订阅、发布...

    Hegel_Gu 评论0 收藏0
  • JavaScript 设计模式(六):观察者模式与发布订阅模式

    摘要:观察者模式维护单一事件对应多个依赖该事件的对象关系发布订阅维护多个事件主题及依赖各事件主题的对象之间的关系观察者模式是目标对象直接触发通知全部通知,观察对象被迫接收通知。 观察者模式(Observer) 观察者模式:定义了对象间一种一对多的依赖关系,当目标对象 Subject 的状态发生改变时,所有依赖它的对象 Observer 都会得到通知。 简单点:女神有男朋友了,朋友圈晒个图,甜...

    bingo 评论0 收藏0

发表评论

0条评论

Yujiaao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<