(18)设计模式

文章目录

    • 1. 定义
    • 2. 通用类图
    • 3. 优点
    • 4. 使用场景
    • 5. 回调的原理
    • 6. 模板模式 VS 回调

1. 定义

模板模式,全称是 模板方法设计模式,英文是 Template Method Design Pattern。定义为:模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。

2. 通用类图

注意:为了防止恶意的操作,一般模板方法都加上 final 关键字,不允许被覆写。

3. 优点

  1. 封庄不变部分,扩展可变部分。
  2. 提取公共部分代码,便于维护。
  3. 行为由父类控制,子类实现。

4. 使用场景

  1. 多个子类有共有的方法,并且逻辑基本相同时。
  2. 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
  3. 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽象到父类中,然后通过钩子函数约束其行为。

5. 回调的原理

回调是一种双向调用关系。A 类事先注册某个函数 F 到 B 类,A 类在调用 B 类的 P 函数的时候,B 类反过来调用 A 类注册给它的 F 函数。这里的 F 函数就是“回调函数”。A 调用 B,B 反过来又调用 A,这种调用机制就叫作 “回调”。

回调可以分为同步回调和异步回调(或者延迟回调)。同步回调指在函数返回之前执行回调函数;异步回调指的是在函数返回之后执行回调函数。

6. 模板模式 VS 回调

从应用场景上来看,同步回调跟模板模式几乎一致。它们都是在一个大的算法骨架中,自由替换其中的某个步骤,起到代码复用和扩展的目的。而异步回调跟模板模式有较大差别,更像是观察者模式。

从代码实现上来看,回调和模板模式完全不同。回调基于组合关系来实现,把一个对象传递给另一个对象,是一种对象之间的关系;模板模式基于继承关系来实现,子类重写父类的抽象方法,是一种类之间的关系。

在代码实现上,回调相对于模板模式会更加灵活,主要体现在下面几点。

  • 像 Java 这种只支持单继承的语言,基于模板模式编写的子类,已经继承了一个父类,不再具有继承的能力。
  • 回调可以使用匿名类来创建回调对象,可以不用事先定义类;而模板模式针对不同的实现都要定义不同的子类。
  • 如果某个类中定义了多个模板方法,每个方法都有对应的抽象方法,那即便只用到其中的一个模板方法,子类也必须实现所有的抽象方法。而回调就更加灵活,只需要往用到的模板方法中注入回调对象即可。

(18)设计模式

文章目录

    • 1. 定义
    • 2. 通用类图
    • 3. 优点
    • 4. 使用场景
    • 5. 回调的原理
    • 6. 模板模式 VS 回调

1. 定义

模板模式,全称是 模板方法设计模式,英文是 Template Method Design Pattern。定义为:模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。

2. 通用类图

注意:为了防止恶意的操作,一般模板方法都加上 final 关键字,不允许被覆写。

3. 优点

  1. 封庄不变部分,扩展可变部分。
  2. 提取公共部分代码,便于维护。
  3. 行为由父类控制,子类实现。

4. 使用场景

  1. 多个子类有共有的方法,并且逻辑基本相同时。
  2. 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
  3. 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽象到父类中,然后通过钩子函数约束其行为。

5. 回调的原理

回调是一种双向调用关系。A 类事先注册某个函数 F 到 B 类,A 类在调用 B 类的 P 函数的时候,B 类反过来调用 A 类注册给它的 F 函数。这里的 F 函数就是“回调函数”。A 调用 B,B 反过来又调用 A,这种调用机制就叫作 “回调”。

回调可以分为同步回调和异步回调(或者延迟回调)。同步回调指在函数返回之前执行回调函数;异步回调指的是在函数返回之后执行回调函数。

6. 模板模式 VS 回调

从应用场景上来看,同步回调跟模板模式几乎一致。它们都是在一个大的算法骨架中,自由替换其中的某个步骤,起到代码复用和扩展的目的。而异步回调跟模板模式有较大差别,更像是观察者模式。

从代码实现上来看,回调和模板模式完全不同。回调基于组合关系来实现,把一个对象传递给另一个对象,是一种对象之间的关系;模板模式基于继承关系来实现,子类重写父类的抽象方法,是一种类之间的关系。

在代码实现上,回调相对于模板模式会更加灵活,主要体现在下面几点。

  • 像 Java 这种只支持单继承的语言,基于模板模式编写的子类,已经继承了一个父类,不再具有继承的能力。
  • 回调可以使用匿名类来创建回调对象,可以不用事先定义类;而模板模式针对不同的实现都要定义不同的子类。
  • 如果某个类中定义了多个模板方法,每个方法都有对应的抽象方法,那即便只用到其中的一个模板方法,子类也必须实现所有的抽象方法。而回调就更加灵活,只需要往用到的模板方法中注入回调对象即可。