回调机制(callback)在编程设计模式中的使用,一文即开窍!

回调机制是编程中的重要概念,适用于多种语言。本文深入探讨回调的声明、注册和触发,以及在设计模式如策略、模板、观察者模式中的应用。回调与正常调用的主要区别在于控制权反转,常用于异步处理和提高框架的拓展性。通过实例,如Minecraft插件开发和业务中的异步回调,进一步解释了回调的实际运用。

什么是回调(callback)机制?

它不限于Java,而是通用的编程机制。

回调的三个阶段:

  • 声明回调:我发了一个帖子,说我后续会继续更新
  • 注册回调:楼下网友订阅了我的帖子等更新
  • 触发回调:我更新了,调用当初的声明回调代码,来通知所有订阅(注册回调)的网友

回调在设计模式中的使用:

  • 策略模式
  • 模板模式
  • 观察者模式
  • 访问者模式

此外:

  • 事件总线
  • 监听器
  • 过滤器
  • 某功能预留的客制化前置后置处理
  • 对接口实现类的调用(创建接口=声明回调;实现接口=注册回调;调用实现类=触发回调)
    • 故此推理:代理也是回调(反射也是?)

都算回调的应用


回调与正常调用的区别:

正常调用:框架开发API,我们调用来使用框架的类和逻辑

(我们 调 框架)(高层 调 底层)

回调:框架的API无法满足我们的调用需求,我们需要自己写一个类注册回调,来触发框架已有的回调机制,从而让框架来调用使用我们的类和逻辑

(框架 调 我们)(底层 反过来 调 高层)


关于声明回调的人有什么必要要这么弄?

就是把功能外包,增加他框架的拓展性

因为在实际开发中,一些耗费时间的工作交给扔出去让其他线程做,自身流程继续。
当交出去的工作做完了,它发一个消息回来,这就叫回调。
所以框架开发者留出可回调的余地,让后续使用框架的程序员能够注册和触发回调,实现客制化、高拓展性、且还可通过异步减少重量级业务对主线程的影响,此外它本质还是个解耦操作。


回调的本质:

有两个类 A B
在A中包含一个B的引用。(A关联B)
B中方法使用A对象作为参数。(B依赖A)
A方法1中调用B的方法2(同时将A对象作参数传给B)
B方法2执行完业务代码后再用A的对象(回)调A的方法3

在A调用B方法2时、或B调用方法3(回调方法)时,如果开启新的线程,就是异步,否则就是同步回调


回调俗称:钩子(Hook)

回调函数:钩子函数


如何理解 “被回调”,“谁对谁回调”的概念

首先:回调函数 (底层)回调
其次:回调函数(callback function)就是高层的客制化逻辑,被底层(框架)回调的函数

关于 A是对B的一个回调 这类术语的理解(以Spring为例):

Spring5 中 InitializingBean接口有288个实现类
而IoC生命周期管理的具体实现方法invokeInitMethods中包含了InitializingBean接口的抽象方法afterPropertiesSet()
invokeInitMethods方法能够接收bean的所有实现类(以Object形式),其中也包含了InitializingBean接口的实现类
所以在invokeInitMethods方法真正执行的时候,afterPropertiesSet一定会被具象地使用,并且能根据288种实现类做出288种不同的afterPropertiesSet逻辑,这些afterPropertiesSet的逻辑都在Runtime期间直接嵌入到invokeInitMethods的逻辑中,智能地执行匹配的invokeInitMethods方法。并且在未来它也还能够支持第289种逻辑,同时不用更改invokeInitMethods的底层代码,符合OCP开发原则。

在这个案例中:

  • 具象的invokeInitMethods方法通过把抽象的afterPropertiesSet方法包含在内,实现了对未来被第三方回调的 - 声明
  • 我们通过实现InitializingBean接口,并通过@Bean将其注册到Spring IoC容器中,实现了回调的 - 注册
  • Spring IoC在运行时调用invokeInitMethods方法,在初始化我们实现InitializingBean接口的bean对象时,执行我们(第三方)自己客制化的afterPropertiesSet方法,实现了回调的 - 触发

其中:
具象的invokeInitMethods方法中包含的抽象的afterPropertiesSet方法 是对 InitializingBean接口的实现类中具象的afterPropertiesSet方法 的回调
这里前者是 A 后者是 B,故称为:A是对B的一个回调


Minecraft插件开发中回调的应用:

同步回调

实现Listener写带有@EventHandler注解的onEventListener方法,
该方法就是Event触发时的回调方法,
它(Listener实现类)的注册需要在Plugin onEnable时注册Listener,
并在Runtime期间通过@EventHandler注解进行调度、和优先级管理等spigot回调函数的附加特性的执行

异步回调

把你写的Listener方法变成异步即是异步回调
比如需要遍历大量方块的方法,改成异步就可以给主线程减负

业务中的异步回调案例:

案例1:

主线程中A开一个新线程去调用B的方法2,方法2结束前调用A的回调方法(方法3)对A进行通知,告诉它“我B做完事儿了”

案例2:

A类(我,代表主线程)去店里(B类)买菜,B说菜没有了,
但他有上菜通知业务(声明回调),我说:“那我走了(开始异步),
但有菜了回头给我来电话(注册回调)”
B说OK。三小时后,B上菜了,
给我(A类)来电话(触发回调),我就回去把菜买了。
期间B忙了三小时的进货,A也没被耽误菜之外其他的事情


Reference及相关阅读:

https://www.zhihu.com/question/25504849
https://www.cnblogs.com/ymczxy/p/4711122.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值