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

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是回调(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
基本概念 if you call me, i will call back 什么是回调函数 回调函数(callback Function),顾名思义,用于回调的函数。 回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数。回调函数是一个工作流的一部分,由工作流来决定函数的调用(回调)时机。回调函数包含下面几个特性: >属于工作流的一个部分; >必须按照工作流指定的调用约定来申明(定义); >他的调用时机由工作流决定,回调函数的实现者不能直接调用回调函数来实现工作流的功能; 回调机制 回调机制是一种常见的设计模型,他把工作流内的某个功能,按照约定的接口暴露给外部使用者,为外部使用者提供数据,或要求外部使用者提供数据。 java回调机制: 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。 >同步调用:一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用; >回 调:一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口; >异步调用:一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。 回调和异步调用的关系非常紧密:使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值