• 事件分发模型的设计与实现


    事件分发模型的设计与实现

    1.事件分发模型

    从组成元素来看,可以为划分:事件(Event),事件的监听(EventListner),事件调度(EventDispather).

    其中事件和事件监听之间是多对多的关系,即一个事件可以有多个监听处理,一个监听也可以处理多种时间。

    2.模型实现

    事件接口:

    public interface Event {
    
    }
    

    事件监听

    public abstract class EventListener {
    
        /**
         * 在初始化listener的同时注册listener
         */
        public EventListener(){
            EventDispatcher.getInstance().registerListener(this);
        }
    
        /**
         * 感兴趣的事件列表
         * @return
         */
        abstract public List<Class<? extends Event>> interest();
    
        /**
         * 处理事件
         * @param event
         */
        abstract public void onEvent(Event event);
    }
    

    事件分发处理(核心)

    public class EventDispatcher {
    
        public final Logger log = LoggerFactory.getLogger(EventDispatcher.class);
        //并发事件组
        public CopyOnWriteArrayList<Entry> listenerHub = new CopyOnWriteArrayList<Entry>();
    
        /**
         * 处理事件
         * @param event
         */
        public void fireEvent(Event event) {
            if (null == event) {
                throw new IllegalArgumentException();
            }
            for (EventListener listener : getEntry(event.getClass()).listeners) {
                try {
                    listener.onEvent(event);
                } catch (Exception e) {
                    log.error(e.toString(), e);
                }
    
            }
        }
    
        /**
         * 注册监听事件
         * @param listener
         */
        public void registerListener(EventListener listener) {
            for (Class<? extends Event> eventClass : listener.interest()) {
                getEntry(eventClass).listeners.addIfAbsent(listener);
            }
        }
    
        /**
         * 清空事件总线
         */
        public void clear() {
            listenerHub.clear();
    
        }
    
        /**
         * 获取事件组
         * @param eventClass
         * @return
         */
        private Entry getEntry(Class<? extends Event> eventClass) {
            for (; ; ) {
                for (Entry entry : listenerHub) {
                    if (entry.eventType == eventClass) {
                        return entry;
                    }
                }
                Entry temp = new Entry(eventClass);
                //如果不存在,才添加
                if (listenerHub.addIfAbsent(temp)) {
                    return temp;
                }
            }
    
        }
    
        /**
         * 按照事件类型,设计一个监听组
         */
        private class Entry {
            final Class<? extends Event> eventType;
            CopyOnWriteArrayList<EventListener> listeners;
    
            Entry(Class<? extends Event> type) {
                eventType = type;
                listeners = new CopyOnWriteArrayList<EventListener>();
            }
    
            @Override
            public boolean equals(Object obj) {
                if (null == obj || (obj.getClass() != this.getClass())) {
                    return false;
                }
                if (obj == this) {
                    return true;
                }
                return eventType == ((Entry) obj).eventType;
            }
    
    
        }
    
        /**
         * 单例控制 EventDispatcher
         */
        private static class EventDispatcherFactory {
            public static EventDispatcher _instance = new EventDispatcher();
        }
    
        public static EventDispatcher getInstance() {
            return EventDispatcherFactory._instance;
        }
        
        private EventDispatcher() {
        }
    }
    

    关键点:

    • 事件分发模型是单例对象,实现并发模式下的初始化,没有用锁
    • 注册监听时,按照事件类型进行监听编组,不存在的事件组,需要考虑并发初始化
    • 采用copyonwritelist,实现列表的并发更新。

    代码地址:

    https://github.com/zhulongchao/eventmodel.git

  • 相关阅读:
    Web Api 模型绑定 二
    C#关键字
    ASP.NET Core MVC 过滤器
    EF性能优化篇一
    Linq
    HTTP协议
    Linux进程管理(11)
    Linux网络配置(10)
    Django模板修炼
    递归
  • 原文地址:https://www.cnblogs.com/zhulongchao/p/5424447.html
Copyright © 2020-2023  润新知