监听者模式
回调函数:
-
往组件注册自定义的方法,以便组件在特定场景下调用—这个方法是组件定义的,业务方实现
@Slf4j public class CallBackDemo { public static void main(String args[]) { Thread thread = new Thread(new Runnable() { @Override public void run() { try { System.out.println("准备休息了"); Thread.sleep(2000); } catch (Exception e) { log.error("线程休眠异常", e); } System.out.println("休息结束了"); System.out.println("线程被回调了"); } }); thread.start(); } }
以上就是一个回调函数,Thread 类就是上面所说的组件,Runnable 接口中定义的 run 方法就是自定义方法(回调函数),我们不希望直接调用 run方法直接执行,而是让 Thread 组件在特殊时刻去执行。该时刻就是在调用 start方法之后再执行,主线程调用 start 方法后会生成一个子线程,子线程会在某个时刻执行自己run方法的时候调用 Runnable接口中实现的 run方法。
事件监听器
监听器将监听自己感兴趣的事件,一旦事件发生,就会做出响应。
事件监听器涉及三个组件:
-
事件源(Event Source)
要想使事件源对某些事件进行响应,就需要在事件源上注册特定的监听器
如按钮
-
监听器(Event Listener)
监听器要注册在事件源上才会被调用,主要用来监听事件,并进行事件的处理和转发
监听到类似按钮被按这样的事件源
-
事件对象(Event Object)
主要负责事件源,和事件监听器之间的信息的传递
使用事件监听器模式可以节约代码,事件监听器 和 事件源 是可以分开开发的。事件监听器 和 事件源 之间使用 事件 进行联系
事件监听器 和 事件源,不用关心彼此实现。
事件监听器就是设计模式中 观察者模式 的实现
事件源,事件—观察者模式中的 主题组件
事件监听器—观察者模式中的 观察者
具体代码实现:
事件:
/**
* @author wsq
* @version Event.java 2020/6/30 上午8:29 下午
* 事件对象--在事件源和事件监听器之间传递信息
*/
@Data
public class Event {
private String type;
}
事件监听器接口定义:
/**
* @author wsq
* @version EventListener.java 2020/6/30 上午8:31 下午
* 监听器接口,具体监听器需要实现这个接口
*/
public interface EventListener {
void processEvent(Event event);
}
具体事件监听器
/**
* @author wsq
* @version SingleClickEventListener.java 2020/6/30 上午8:33 下午
* 单击监听器接口
*/
public class SingleClickEventListener implements EventListener {
@Override
public void processEvent(Event event) {
if ("singleClick".equals(event.getType())) {
System.out.println("单击被触发");
}
}
}
/**
* @author wsq
* @version DoubleClickEventListener.java 2020/6/30 上午8:37 下午
* 双击监听器接口
*/
public class DoubleClickEventListener implements EventListener {
@Override
public void processEvent(Event event) {
if ("doubleClick".equals(event.getType())) {
System.out.println("双击被触发");
}
}
}
事件源:
/**
* @author wsq
* @version EventSource.java 2020/6/30 上午8:36 下午
* 事件源 -- 事件监听器 需要注册到事件源上,事件源有多个 使用 List 接收
* 对外提供事件监听器注册接口
* 发布事件
*/
public class EventSource {
private List<EventListener> listeners = new ArrayList<>();
/**
* 对外暴露 注册 事件监听器的 口子
*
* @param listener
*/
public void register(EventListener listener) {
listeners.add(listener);
}
/**
* 事件源发布事件
*
* @param event 事件源
*/
public void publishEvent(Event event) {
//对 注册到 事件源 的 不同事件监听器 都发布事件
//由事件监听器决定是否响应事件 -- 即事件源发布的事件 是否是自己感兴趣的事件,是就做出响应,否则忽略
for (EventListener listener : listeners) {
listener.processEvent(event);
}
}
}
程序入口:
public class EventModeDemo {
public static void main(String args[]) {
EventSource source = new EventSource();
SingleClickEventListener singleClickEventListener = new SingleClickEventListener();
DoubleClickEventListener doubleClickEventListener = new DoubleClickEventListener();
//往 事件源 注册不同的 事件监听器
source.register(singleClickEventListener);
source.register(doubleClickEventListener);
// 对所有事件监听器 广播发布单击事件
Event singleClickEvent = new Event();
singleClickEvent.setType("singleClick");
source.publishEvent(singleClickEvent);
}
}
输出:
单击被触发
Process finished with exit code 0