设计模式之美
王争
前Google工程师,《数据结构与算法之美》专栏作者
立即订阅
21264 人已学习
课程目录
已更新 65 讲 / 共 100 讲
0/6登录后,你可以任选6讲全文学习。
开篇词 (1讲)
开篇词 | 一对一的设计与编码集训,让你告别没有成长的烂代码!
免费
设计模式学习导读 (3讲)
01 | 为什么说每个程序员都要尽早地学习并掌握设计模式相关知识?
02 | 从哪些维度评判代码质量的好坏?如何具备写出高质量代码的能力?
03 | 面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?
设计原则与思想:面向对象 (11讲)
04 | 理论一:当谈论面向对象的时候,我们到底在谈论什么?
05 | 理论二:封装、抽象、继承、多态分别可以解决哪些编程问题?
06 | 理论三:面向对象相比面向过程有哪些优势?面向过程真的过时了吗?
07 | 理论四:哪些代码设计看似是面向对象,实际是面向过程的?
08 | 理论五:接口vs抽象类的区别?如何用普通的类模拟抽象类和接口?
09 | 理论六:为什么基于接口而非实现编程?有必要为每个类都定义接口吗?
10 | 理论七:为何说要多用组合少用继承?如何决定该用组合还是继承?
11 | 实战一(上):业务开发常用的基于贫血模型的MVC架构违背OOP吗?
12 | 实战一(下):如何利用基于充血模型的DDD开发一个虚拟钱包系统?
13 | 实战二(上):如何对接口鉴权这样一个功能开发做面向对象分析?
14 | 实战二(下):如何利用面向对象设计和编程开发接口鉴权功能?
设计原则与思想:设计原则 (12讲)
15 | 理论一:对于单一职责原则,如何判定某个类的职责是否够“单一”?
16 | 理论二:如何做到“对扩展开放、修改关闭”?扩展和修改各指什么?
17 | 理论三:里式替换(LSP)跟多态有何区别?哪些代码违背了LSP?
18 | 理论四:接口隔离原则有哪三种应用?原则中的“接口”该如何理解?
19 | 理论五:控制反转、依赖反转、依赖注入,这三者有何区别和联系?
20 | 理论六:我为何说KISS、YAGNI原则看似简单,却经常被用错?
21 | 理论七:重复的代码就一定违背DRY吗?如何提高代码的复用性?
22 | 理论八:如何用迪米特法则(LOD)实现“高内聚、松耦合”?
23 | 实战一(上):针对业务系统的开发,如何做需求分析和设计?
24 | 实战一(下):如何实现一个遵从设计原则的积分兑换系统?
25 | 实战二(上):针对非业务的通用框架开发,如何做需求分析和设计?
26 | 实战二(下):如何实现一个支持各种统计规则的性能计数器?
设计原则与思想:规范与重构 (11讲)
27 | 理论一:什么情况下要重构?到底重构什么?又该如何重构?
28 | 理论二:为了保证重构不出错,有哪些非常能落地的技术手段?
29 | 理论三:什么是代码的可测试性?如何写出可测试性好的代码?
30 | 理论四:如何通过封装、抽象、模块化、中间层等解耦代码?
31 | 理论五:让你最快速地改善代码质量的20条编程规范(上)
32 | 理论五:让你最快速地改善代码质量的20条编程规范(中)
33 | 理论五:让你最快速地改善代码质量的20条编程规范(下)
34 | 实战一(上):通过一段ID生成器代码,学习如何发现代码质量问题
35 | 实战一(下):手把手带你将ID生成器代码从“能用”重构为“好用”
36 | 实战二(上):程序出错该返回啥?NULL、异常、错误码、空对象?
37 | 实战二(下):重构ID生成器项目中各函数的异常处理代码
设计原则与思想:总结课 (3讲)
38 | 总结回顾面向对象、设计原则、编程规范、重构技巧等知识点
39 | 运用学过的设计原则和思想完善之前讲的性能计数器项目(上)
40 | 运用学过的设计原则和思想完善之前讲的性能计数器项目(下)
设计模式与范式:创建型 (7讲)
41 | 单例模式(上):为什么说支持懒加载的双重检测不比饿汉式更优?
42 | 单例模式(中):我为什么不推荐使用单例模式?又有何替代方案?
43 | 单例模式(下):如何设计实现一个集群环境下的分布式单例模式?
44 | 工厂模式(上):我为什么说没事不要随便用工厂模式创建对象?
45 | 工厂模式(下):如何设计实现一个Dependency Injection框架?
46 | 建造者模式:详解构造函数、set方法、建造者模式三种对象创建方式
47 | 原型模式:如何最快速地clone一个HashMap散列表?
设计模式与范式:结构型 (8讲)
48 | 代理模式:代理在RPC、缓存、监控等场景中的应用
49 | 桥接模式:如何实现支持不同类型和渠道的消息推送系统?
50 | 装饰器模式:通过剖析Java IO类库源码学习装饰器模式
51 | 适配器模式:代理、适配器、桥接、装饰,这四个模式有何区别?
52 | 门面模式:如何设计合理的接口粒度以兼顾接口的易用性和通用性?
53 | 组合模式:如何设计实现支持递归遍历的文件系统目录树结构?
54 | 享元模式(上):如何利用享元模式优化文本编辑器的内存占用?
55 | 享元模式(下):剖析享元模式在Java Integer、String中的应用
设计模式与范式:行为型 (6讲)
56 | 观察者模式(上):详解各种应用场景下观察者模式的不同实现方式
57 | 观察者模式(下):如何实现一个异步非阻塞的EventBus框架?
58 | 模板模式(上):剖析模板模式在JDK、Servlet、JUnit等中的应用
59 | 模板模式(下):模板模式与Callback回调函数有何区别和联系?
60 | 策略模式(上):如何避免冗长的if-else/switch分支判断代码?
61 | 策略模式(下):如何实现一个支持给不同大小文件排序的小程序?
不定期加餐 (3讲)
加餐一 | 用一篇文章带你了解专栏中用到的所有Java语法
加餐二 | 设计模式、重构、编程规范等相关书籍推荐
春节特别加餐 | 王争:如何学习《设计模式之美》专栏?
免费
设计模式之美
登录|注册

59 | 模板模式(下):模板模式与Callback回调函数有何区别和联系?

王争 2020-03-18
上一节课中,我们学习了模板模式的原理、实现和应用。它常用在框架开发中,通过提供功能扩展点,让框架用户在不修改框架源码的情况下,基于扩展点定制化框架的功能。除此之外,模板模式还可以起到代码复用的作用。
复用和扩展是模板模式的两大作用,实际上,还有另外一个技术概念,也能起到跟模板模式相同的作用,那就是回调(Callback)。今天我们今天就来看一下,回调的原理、实现和应用,以及它跟模板模式的区别和联系。
话不多说,让我们正式开始今天的学习吧!

回调的原理解析

相对于普通的函数调用来说,回调是一种双向调用关系。A 类事先注册某个函数 F 到 B 类,A 类在调用 B 类的 P 函数的时候,B 类反过来调用 A 类注册给它的 F 函数。这里的 F 函数就是“回调函数”。A 调用 B,B 反过来又调用 A,这种调用机制就叫作“回调”。
A 类如何将回调函数传递给 B 类呢?不同的编程语言,有不同的实现方法。C 语言可以使用函数指针,Java 则需要使用包裹了回调函数的类对象,我们简称为回调对象。这里我用 Java 语言举例说明一下。代码如下所示:
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.");
}
});
}
}
上面就是 Java 语言中回调的典型代码实现。从代码实现中,我们可以看出,回调跟模板模式一样,也具有复用和扩展的功能。除了回调函数之外,BClass 类的 process() 函数中的逻辑都可以复用。如果 ICallback、BClass 类是框架代码,AClass 是使用框架的客户端代码,我们可以通过 ICallback 定制 process() 函数,也就是说,框架因此具有了扩展的能力。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《设计模式之美》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(26)

  • 唔多志
    模板方法和回调应用场景是一致的,都是定义好算法骨架,并对外开放扩展点,符合开闭原则;两者的却别是代码的实现上不同,模板方法是通过继承来实现,是自己调用自己;回调是类之间的组合。
    2020-03-18
    12
  • L!en6o
    曾经重构代码对这模板模式和callback就很疑惑。个人觉得callback更加灵活,适合算法逻辑较少的场景,实现一两个方法很舒服。比如Guava 的Futures.addCallback 回调 onSuccess onFailure方法。而模板模式适合更加复杂的场景,并且子类可以复用父类提供的方法,根据场景判断是否需要重写更加方便。
    2020-03-19
    4
  • 黄林晴
    打卡
    回调接口如果定义了多个方法,不也需要全部实现吗

    课后思考:
    android 中有个hook 概念,多用于反射修改源码机制,进行插件化相关的开发
    2020-03-18
    1
    4
  • 小晏子
    callback和hook不是一个层面的东西,callback是程序设计方面的一种技术手段,是编程语言成面的东西,hook是通过这种技术手段实现的功能扩展点,其基本原理就是callback。比如windows api中提供的各种事件通知机制,其本身是windows开放给用户可以扩展自己想要的功能的扩展点,而实现这些功能的手段是callback。
    只要编程语言支持传递函数作为参数,都可以支持callback设计,比如c,golang,javascript,python等。另外一些框架中提供的功能扩展点我们称之为hook,比如vue在其实例生命周期中提供的各种hook函数。
    2020-03-18
    4
  • iLeGeND
    回调函数是不是只能在同一个jvm下的 程序之间才能实现
    2020-03-19
    2
  • Fstar
    Callback 是在一个方法的执行中,调用嵌入的其他方法的机制,能很好地起到代码复用和框架扩展的作用。在 JavaScript 中,因为函数可以直接作为另一个函数的参数,所以能经常看到回调函数的身影,比如定时器 setTimeout(callback, delay)、Ajax 请求成功或失败对应的回调函数等。不过如果滥用回调的话,会在某些场景下会因为嵌套过多导致回调地狱。

    Hook 本质上也是回调,但它往往和一些场景性的行为绑定在一起。在浏览器环境中,我们可以通过 img.onload = func1 来让图片在加载完后执行函数 func1,某种意义上算是一种 Hook。此外在 js 的 vue 框架中,也提供了组件生命周期的 Hook,比如 beforeDestory 钩子函数会在组件即将被销毁前执行,常用于销毁一些当前组件才会用到的定时器。
    2020-03-19
    2
  • Frank
    打卡 今日学习回调函数,收获如下: 回调是一种A调用B,B又回来调用A的一种机制。它有两种方式:同步回调和异步回调。它的功能与模版模式类似都是复用与扩展。回调采用的是组合方式,更加灵活。而模版模式采用的是继承,有单继承的局限,如果继承层次过深,后期不便于维护。自己在写JavaScript时,常常使用回调这种方式来完成需求,通过今日的学习,进一步加深了对回调机制的理解。
    2020-03-18
    2
  • pedro
    callback应该偏语言层面,hook偏业务层面,二者一个是概念,一个是具体的落地方式。
    2020-03-18
    2
  • 大头
    java8支持参数传递,以及lambda的使用,也是对回掉的简化
    2020-03-18
    2
  • Rain
    对于callback 和 hook 的提供意图来说,提供callback 的时候是希望在callback里面完成主要的工作。hook的目的则在于扩展。前者的提供者通常没我在默认实现,非常希望callback 完成具体任务,而hook是基本已经实现了大部分功能,如果需要特殊操作,那就在hook里面做。
    2020-03-19
    1
  • L🚲🐱
    模板方法和回调应用场景一致, 两者的区别是代码实现上不一样, 模板方法是通过 继承来实现, 是自己调用自己, 回调是通过组合来实现, 是类之间的组合. java 中有 Callback的概念
    2020-03-19
    1
  • Jxin
    1.callback是一个语法机制的命名,hook是一个应用场景的命名。但我认为两者换下语义更强。hook描述语法机制,指的就是添加钩子方法这么一种语法机制。callback描述应用场景,特指调用方需要被调用方回调自己的这种场景,这属于钩子方法的应用。大白话就是,我在用callback语法机制时,时常是做一些任务编排的事,跟回调这个语义并不贴切,让我觉得很别扭。

    2.java的jdbc其实操作数据库也有callback语法的应用。但现在都是用的orm框架,估摸也都忘了吧,不过也确实没有记忆的必要就是了。
    2020-03-19
    1
  • 柠檬C
    个人看法:模板模式关注点还是在类与对象上,通过继承与多态实现算法的扩展
    回调关注点在方法上,虽然在java语言中不得不以匿名内部类的形式出现,但本质是将方法当做参数一样传递,有点函数式编程的意思了
    2020-03-19
    1
  • Michael
    swift和OC的闭包也属于回调
    2020-03-19
    1
  • 花郎世纪
    深度学习pytorch框架,提供hook去获取特征层数据
    2020-03-19
    1
  • 丁乐洪
    模板类 与 模板模式 有啥关系,感觉干的是同类活
    2020-03-18
    1
  • Heaven
    对于Java中的Callback,常见的还是异步回调,注册一个函数之后,无需等待返回了,可以进行下一步的工作,仿佛就是种下了一个种子,等待开花结果
    对于Hook,则像是一种具体的实现手段,而且常见于AOP的代理之中
    2020-03-18
    1
  • 徐旭
    hook也是钩子吧,好像也可以用在上层直接调底层native层
    2020-03-18
    1
  • www.xnsms.com小鸟接码
    打卡打卡.....滴,学生卡
    2020-03-18
    1
  • dongdong
    行为模式什么时候更新
    2020-03-18
    1
收起评论
26
返回
顶部