没有合适的资源?快使用搜索试试~ 我知道了~
资源详情
资源评论
资源推荐
59 | 模板模式(下):模板模式与Callback回调函数有何区别和联
系?
2020-03-18 王争
设计模式之美
进入课程
讲述:冯永吉
时长 11:07 大小 10.19M
上一节课中,我们学习了模板模式的原理、实现和应用。它常用在框架开发中,通过提供功
能扩展点,让框架用户在不修改框架源码的情况下,基于扩展点定制化框架的功能。除此之
外,模板模式还可以起到代码复用的作用。
复用和扩展是模板模式的两大作用,实际上,还有另外一个技术概念,也能起到跟模板模式
相同的作用,那就是回调(Callback)。今天我们今天就来看一下,回调的原理、实现和应
用,以及它跟模板模式的区别和联系。
话不多说,让我们正式开始今天的学习吧!
下载APP
回调的原理解析
相对于普通的函数调用来说,回调是一种双向调用关系。A 类事先注册某个函数 F 到 B
类,A 类在调用 B 类的 P 函数的时候,B 类反过来调用 A 类注册给它的 F 函数。这里的 F
函数就是“回调函数”。A 调用 B,B 反过来又调用 A,这种调用机制就叫作“回调”。
A 类如何将回调函数传递给 B 类呢?不同的编程语言,有不同的实现方法。C 语言可以使
用函数指针,Java 则需要使用包裹了回调函数的类对象,我们简称为回调对象。这里我用
Java 语言举例说明一下。代码如下所示:
上面就是 Java 语言中回调的典型代码实现。从代码实现中,我们可以看出,回调跟模板模
式一样,也具有复用和扩展的功能。除了回调函数之外,BClass 类的 process() 函数中的
逻辑都可以复用。如果 ICallback、BClass 类是框架代码,AClass 是使用框架的客户端代
码,我们可以通过 ICallback 定制 process() 函数,也就是说,框架因此具有了扩展的能
力。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public interface ICallback {
void methodToCallback();
}
public class BClass {
public void process(ICallback callback) {
//...
callback.methodToCallback();
//...
}
}
public class AClass {
public static void main(String[] args) {
BClass b = new BClass();
b.process(new ICallback() { //回调对象
@Override
public void methodToCallback() {
System.out.println("Call back me.");
}
});
}
}
实际上,回调不仅可以应用在代码设计上,在更高层次的架构设计上也比较常用。比如,通
过三方支付系统来实现支付功能,用户在发起支付请求之后,一般不会一直阻塞到支付结果
返回,而是注册回调接口(类似回调函数,一般是一个回调用的 URL)给三方支付系统,
等三方支付系统执行完成之后,将结果通过回调接口返回给用户。
回调可以分为同步回调和异步回调(或者延迟回调)。同步回调指在函数返回之前执行回调
函数;异步回调指的是在函数返回之后执行回调函数。上面的代码实际上是同步回调的实现
方式,在 process() 函数返回之前,执行完回调函数 methodToCallback()。而上面支付的
例子是异步回调的实现方式,发起支付之后不需要等待回调接口被调用就直接返回。从应用
场景上来看,同步回调看起来更像模板模式,异步回调看起来更像观察者模式。
应用举例一:JdbcTemplate
Spring 提供了很多 Template 类,比如,JdbcTemplate、RedisTemplate、
RestTemplate。尽管都叫作 xxxTemplate,但它们并非基于模板模式来实现的,而是基于
回调来实现的,确切地说应该是同步回调。而同步回调从应用场景上很像模板模式,所以,
在命名上,这些类使用 Template(模板)这个单词作为后缀。
这些 Template 类的设计思路都很相近,所以,我们只拿其中的 JdbcTemplate 来举例分
析一下。对于其他 Template 类,你可以阅读源码自行分析。
在前面的章节中,我们也多次提到,Java 提供了 JDBC 类库来封装不同类型的数据库操
作。不过,直接使用 JDBC 来编写操作数据库的代码,还是有点复杂的。比如,下面这段
是使用 JDBC 来查询用户信息的代码。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
public class JdbcDemo {
public User queryUser(long id) {
Connection conn = null;
Statement stmt = null;
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo", "x
//2.创建statement类对象,用来执行SQL语句
stmt = conn.createStatement();
//3.ResultSet类,用来存放获取的结果集
剩余14页未读,继续阅读
东方捕
- 粉丝: 15
- 资源: 310
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 老飞飞搭建基础通用数据库V19数据库.rar
- jquery.js
- 机械设计多工位ACF贴胶带&预压设备sw18可编辑非常好的设计图纸100%好用.zip
- 基于Pytorch复现Point-Transformer,用于ShapeNet数据集点云分割
- 【医学影像分析】2D超声图像的分割检测(Ultrasound Nerve Segmentation - Kaggle数据集)
- 嘎嘎香的五款神仙谷歌插件
- .arch书源导入教程.mp4
- 贪心算法介绍及代码示例讲解
- CR13SP35MSI64 Crystal 水晶报表运行组件最后版本64位
- 图像分类数据集:玉米叶是否感染分类数据集(2分类,包含训练集、验证集)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0