模板模式
模板模式常用在框架开发中,通过提供功能扩展点,让框架用户在不修改源码框架的情况下,基于扩展点定制化框架功能,模板模式还可以起到代码复用的作用。复用和扩展是模板模式的两大作用。
回调
相对于普通的函数调用来说,回调是一种双向调用关系。A类事先注册某个函数F到B类,A类在调用B类的P函数的时候,B反过来调用A类注册给他的F函数。这里的F函数就是“回调函数”。A调用B,B反过来调用A,这种调用机制就叫做“回调”。
A类如何将回调函数传递给B类呢?不同的编程语言,有不同的实现方式,C语言可以使用函数指针,PHP则需要使用包括了回调函数的类对象,我们简称为回调对象。这里我用PHP语言举例说明下。代码如下所示:
1 | interface ICallback { |
上面就是PHP语言的代码实现。从代码中我们可以看出,回调跟模板模式一样,也具有复用和扩展的功能。除了回调函数之外,Bclass类的doSomething()函数中的逻辑都可以复用。如果ICallback、Bclass类是框架代码,Aclass是使用了框架的客户端代码,我们可以通过ICallback定制callback()函数,也就是说,框架因此具有了扩展的能力。
实际上,回调不仅可以应用在代码设计上,更高层次的架构设计上也比较常用。比如通过第三方支付系统来实现支付功能,用户再发起支付请求后,一般不会一直阻塞到支付结果返回,而是注册回调接口给第三方系统,等第三方系统执行完成后,将结果通过回调接口返回给用户。
回调可以分为同步回调和异步回调。同步回调指在函数返回之前执行回调函数;异步回调指的是在返回之后执行回调函数。上面的代码实际上是同步回调的实现方式。而上面支付的例子是异步回调的实现方式。从应用场景上来看,同步回调看起来更像模板模式,异步回调看起来更像观察者模式。
Hook
Hook可以翻译成“钩子”,那它跟Callback有什么区别呢?
网上有人认为Hook就是Callback,两者说的是一回事,只是表达不同而已。而有人觉得Hook是Callback的一种应用。Callback更侧重语法机制的描述,Hook更加侧重应用场景的描述。到底那种说法更准确,这个其实不重要,我们只需要见了代码能认识,遇到场景会用就可以了。
模板模式 VS 回调
从应用场景上来看,同步回调跟模板模式几乎一致。它们都是在一个大的算法骨架中,自由替换其中的某个步骤,起到代码复用和扩展的目的。而异步回调跟模板模式有较大差异,更像是观察者模式。
从代码实现上来看,回调和模板模式完全不同。回调基于组合关系来实现,把一个对象传递给另一个对象,是一种对象之间的组合关系;模板模式基于继承关系来实现,子类重写父类的抽象方法,是一种类之间的关系。
我们经常说“组合优于继承”。实际上,这里也不例外,在代码实现上,回调相对于模板模式会更加灵活。