关于事件监听我们需要知道的一些基础知识。
a)事件三要素(who when what):
source --事件源
when--事件发生时间
message-- 事件主题消息,即希望通过事件传递出去的信息
b)事件模型的构成:
event --事件
source--事件源
listener-- 事件监听器
c)事件流转过程:
(1)事件源注册监听器 -> (2)事件发生 -> (3)通知监听器 -> (4)监听器处理
那么基于以上背景知识,我们来是实现一个简单的监听器,并测试一下事件监听的完整流程。
根据事件三要素设计出一个简单合理的事件载体:Event
public interface Event extendsSerializable {
Object getSource();
Date getWhen();
String getMessage();/*** 事件回调方法*/
voidcallback();
}
事件实现:MyEvent
public class MyEvent implementsEvent {private Log log =LogFactory.getLog(getClass());private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");privateObject source;privateDate when;privateString message;
@OverridepublicObject getSource() {returnsource;
}public voidsetSource(Object source) {this.source =source;
}
@OverridepublicDate getWhen() {returnwhen;
}public voidsetWhen(Date when) {this.when =when;
}
@OverridepublicString getMessage() {returnmessage;
}public voidsetMessage(String message) {this.message =message;
}
@Overridepublic voidcallback() {
log.info(toString());
}
@OverridepublicString toString() {return "source: " + getSource() + ", message: " + getMessage() + ", when: " +sdf.format(getWhen());
}
}
View Code
监听器接口:EventListener
public interfaceEventListener {/*** 事件触发
*@paramevent*/
voidhandleEvent(Event event);
}
监听器实现:MyListener
public class MyListener implementsEventListener {@Overridepublic voidhandleEvent(Event event) {event.callback();
}
}
事件源接口:EventSource
public interfaceEventSource {/*** 增加监听器
*@paramlistener*/
voidaddListener(EventListener listener);/*** 通知监听器*/
voidnotifyListener();
}
编写测试的事件源:MySource
public class MySource implementsEventSource {private List listeners = new ArrayList();private intvalue;
@Overridepublic voidaddListener(EventListener listener) {
listeners.add(listener);
}
@Overridepublic voidnotifyListener() {for(EventListener listener : listeners) {
MyEvent event= newMyEvent();
event.setSource(this);
event.setWhen(newDate());
event.setMessage("setValue " +value);
listener.handleEvent(event);
}
}public intgetValue() {returnvalue;
}public void setValue(intvalue) {this.value =value;
notifyListener();
}
@Testpublic voidtestEventListener() {
MySource source= newMySource();
source.addListener(newMyListener());
source.setValue(100);
}
}
测试输出:
[INFO]-[Event-callback(50)]: source: com.lichmama.test.listen.MySource@119126ab, message: setValue 100, when: 2018-05-01 02:52:13
*PS:监听器模式和观察者模式看起来很像,不过在事件模型的设置上有些许差别。在观察者模式中并没有Event这个角色,或者说它被合并到Observable角色中了,即整合了事件源与事件。