当我们看到下面代码的时候,我们需要清楚的知道背后发生了什么?

  1. //object发布了一个事件
  2. object.publish(event);

object肯定内部维护了一个list,list里面存放的是一个一个监听器listener,pubish内部会遍历这个list,调用监听器的公共方法,这个方法会根据事件的类型作出相应的逻辑处理。

监听器就是希望事件的连续发生,A发布了一件事情,击鼓传花触发了B的发生。隐式发生。
关键词,链表,遍历,注册,通知

事件的触发是由事件源对象主动发起。非异步,顺序执行的

测试

比如偶像开始努力看书,那么粉丝受到影响也开始好好学习了。那如何用代码去实现这个功能呢?
我们把偶像当做事件源
看书作为事件对象
粉丝开始学习作为监听器

  1. package com.zstu.boot.study.controller;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. public class Listener {
  5. public static void main(String[] args) {
  6. SuperStarEventSource superStarEventSource = new SuperStarEventSource("易烊千玺");
  7. FansListener fans1 = new FansListener("粉丝1");
  8. FansListener fans2 = new FansListener("粉丝2");
  9. superStarEventSource.registerFansListener(fans1);
  10. superStarEventSource.registerFansListener(fans2);
  11. superStarEventSource.notify(new EventObject("看书"));
  12. }
  13. }
  14. class SuperStarEventSource{
  15. public String eventSourceName;
  16. public SuperStarEventSource(String eventSourceName) {
  17. this.eventSourceName = eventSourceName;
  18. }
  19. public List<FansListener> fansList = new ArrayList<>();
  20. public void registerFansListener(FansListener fansListener){
  21. fansList.add(fansListener);
  22. }
  23. public void notify(EventObject event){
  24. for (FansListener fansListener : fansList) {
  25. fansListener.handleEvent(event);
  26. }
  27. }
  28. }
  29. class FansListener{
  30. public String listenerName;
  31. public FansListener(String listenerName) {
  32. this.listenerName = listenerName;
  33. }
  34. public void handleEvent(EventObject event){
  35. if(event.name.equals("看书")){
  36. System.out.println(this.listenerName + "我要学习");
  37. }else if(event.name.equals("打球")){
  38. System.out.println(this.listenerName + "我要运动");
  39. }
  40. };
  41. }
  42. class EventObject{
  43. public String name;
  44. public EventObject(String name) {
  45. this.name = name;
  46. }
  47. }

回调

我们希望在执行完A方法后,需要立刻去执行B方法,如果不用回调的方式就是顺序执行AB方法

  1. methodA();
  2. methodB();

这样子将方法A和方法B独立开来,看不出A和B之间的联系。我们可以用回调的方式

  1. methodA(()->methodB());

其实就是在A方法的内部调用了B。仅此而已。

参考