事件分发模型的设计与实现
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,实现列表的并发更新。
代码地址: