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

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

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

原文地址:https://www.cnblogs.com/zhulongchao/p/5424447.html