关于事件监听我们需要知道的一些基础知识。
a)事件三要素:
source — 事件源
when — 事件发生时间
message — 事件主题消息,即希望通过事件传递出去的信息
b)事件流转过程:
(1)事件源注册监听器 -> (2)事件发生 -> (3)通知监听器 -> (4)监听器处理
那么基于以上背景知识,我们来是实现一个简单的监听器,并测试一下事件监听的完整流程。
根据事件三要素设计出一个简单合理的事件载体:Event
public class Event implements Serializable {
private Object source;
private Date when;
private String message;
public Object getSource() {
return source;
}
public void setSource(Object source) {
this.source = source;
}
public Date getWhen() {
return when;
}
public void setWhen(Date when) {
this.when = when;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
监听器接口:EventListener
public interface EventListener {
/**
* 事件触发
* @param event
*/
void handleEvent(Event event);
}
监听器实现:MyListener
public class MyListener implements EventListener {
private Log log = LogFactory.getLog(getClass());
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
@Override
public void handleEvent(Event event) {
log.info("source: " + event.getSource() + ", message: " + event.getMessage() + ", when: "
+ sdf.format(event.getWhen()));
}
}
为了规范化,我们在这里制定一个事件源接口:EventSource
public interface EventSource {
/**
* 增加监听器
* @param listener
*/
void addListener(EventListener listener);
/**
* 通知监听器
*/
void notifyListeners();
}
编写测试的事件源:MySource
public class MySource implements EventSource {
private List<EventListener> listeners = new ArrayList<EventListener>();
private int value;
@Override
public void addListener(EventListener listener) {
listeners.add(listener);
}
@Override
public void notifyListeners() {
for (EventListener listener : listeners) {
Event event = new Event();
event.setSource(this);
event.setWhen(new Date());
event.setMessage("setValue " + value);
listener.handleEvent(event);
}
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
notifyListener();
}
public static void main(String[] args) {
MySource source = new MySource();
source.addListener(new MyListener());
source.setValue(100);
}
}
测试输出:
[INFO]-[MyListener-handleEvent(16)]: source: [email protected], message: setValue 100, when: 2018-05-01 01:18:35
*PS:是不是觉得这个跟观察者设计模式很像,没错。就效果而言,事件监听器模式和观察者模式并没有什么区别,不过在事件模型的设置上有些许差别。在观察者模式中并没有Event这个角色,或者说它被合并到Observable角色中了,即整合了事件源与事件。