关于事件监听我们需要知道的一些基础知识。

    a)事件三要素:
    source — 事件源
    when — 事件发生时间
    message — 事件主题消息,即希望通过事件传递出去的信息

    b)事件流转过程:
    (1)事件源注册监听器 -> (2)事件发生 -> (3)通知监听器 -> (4)监听器处理

    那么基于以上背景知识,我们来是实现一个简单的监听器,并测试一下事件监听的完整流程。
    根据事件三要素设计出一个简单合理的事件载体:Event

    1. public class Event implements Serializable {
    2. private Object source;
    3. private Date when;
    4. private String message;
    5. public Object getSource() {
    6. return source;
    7. }
    8. public void setSource(Object source) {
    9. this.source = source;
    10. }
    11. public Date getWhen() {
    12. return when;
    13. }
    14. public void setWhen(Date when) {
    15. this.when = when;
    16. }
    17. public String getMessage() {
    18. return message;
    19. }
    20. public void setMessage(String message) {
    21. this.message = message;
    22. }
    23. }

    监听器接口:EventListener

    1. public interface EventListener {
    2. /**
    3. * 事件触发
    4. * @param event
    5. */
    6. void handleEvent(Event event);
    7. }

    监听器实现:MyListener

    1. public class MyListener implements EventListener {
    2. private Log log = LogFactory.getLog(getClass());
    3. private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    4. @Override
    5. public void handleEvent(Event event) {
    6. log.info("source: " + event.getSource() + ", message: " + event.getMessage() + ", when: "
    7. + sdf.format(event.getWhen()));
    8. }
    9. }

    为了规范化,我们在这里制定一个事件源接口:EventSource

    1. public interface EventSource {
    2. /**
    3. * 增加监听器
    4. * @param listener
    5. */
    6. void addListener(EventListener listener);
    7. /**
    8. * 通知监听器
    9. */
    10. void notifyListeners();
    11. }

    编写测试的事件源:MySource

    1. public class MySource implements EventSource {
    2. private List<EventListener> listeners = new ArrayList<EventListener>();
    3. private int value;
    4. @Override
    5. public void addListener(EventListener listener) {
    6. listeners.add(listener);
    7. }
    8. @Override
    9. public void notifyListeners() {
    10. for (EventListener listener : listeners) {
    11. Event event = new Event();
    12. event.setSource(this);
    13. event.setWhen(new Date());
    14. event.setMessage("setValue " + value);
    15. listener.handleEvent(event);
    16. }
    17. }
    18. public int getValue() {
    19. return value;
    20. }
    21. public void setValue(int value) {
    22. this.value = value;
    23. notifyListener();
    24. }
    25. public static void main(String[] args) {
    26. MySource source = new MySource();
    27. source.addListener(new MyListener());
    28. source.setValue(100);
    29. }
    30. }

    测试输出:

    1. [INFO]-[MyListener-handleEvent(16)]: source: [email protected], message: setValue 100, when: 2018-05-01 01:18:35

    *PS:是不是觉得这个跟观察者设计模式很像,没错。就效果而言,事件监听器模式和观察者模式并没有什么区别,不过在事件模型的设置上有些许差别。在观察者模式中并没有Event这个角色,或者说它被合并到Observable角色中了,即整合了事件源与事件。