模板模式

模板模式(Template Pattern)是一种行为型设计模式,它定义了一个操作的算法骨架,将某些步骤的实现延迟到子类中。模板模式通过在抽象类中定义通用的算法结构,并允许子类重写特定步骤,从而实现代码复用和行为一致性。它常用于需要固定流程但部分步骤可自定义的场景。

模板模式的组成

模板模式通常包含以下几个角色:

  1. 抽象模板(Abstract Template):定义算法的骨架,包含模板方法(通常是 final 的)和需要子类实现的抽象方法。
  2. 具体模板(Concrete Template):继承抽象模板,实现抽象方法,定义具体步骤的行为。
  3. 客户端(Client):调用模板方法,执行算法流程。

工作原理

  1. 抽象模板类中定义了一个模板方法,描述了算法的整体流程,调用一系列步骤(包括抽象方法和具体方法)。
  2. 子类继承抽象模板类,实现抽象方法,提供具体步骤的实现。
  3. 客户端通过调用模板方法,触发整个算法流程,具体行为由子类决定。

UML 类图

┌────────────────────┐
│  AbstractTemplate  │
├────────────────────┤
│ templateMethod()   │
│ step1()            │
│ step2()            │
│ step3()            │
└────────────────────┘
           ↑
           │
┌────────────────────┐       ┌────────────────────┐
│ ConcreteTemplateA  │       │ ConcreteTemplateB  │
├────────────────────┤       ├────────────────────┤
│ step1()            │       │ step1()            │
│ step2()            │       │ step2()            │
└────────────────────┘       └────────────────────┘

代码示例(以 Java 为例)

以下是一个模板模式的实现,模拟不同类型饮料的制作流程:


// 抽象模板类
abstract class BeverageMaker {
// 模板方法,定义饮料制作流程
final void prepareBeverage() {
boilWater();
brew();
pourInCup();
addCondiments();
}

// 固定步骤
void boilWater() {
    System.out.println("烧开水");
}

void pourInCup() {
    System.out.println("倒入杯子");
}

// 抽象步骤,由子类实现
abstract void brew();
abstract void addCondiments();

}

// 具体模板类:咖啡
class CoffeeMaker extends BeverageMaker {
@Override
void brew() {
System.out.println(“冲泡咖啡”);
}

@Override
void addCondiments() {
    System.out.println("添加糖和奶");
}

}

// 具体模板类:茶
class TeaMaker extends BeverageMaker {
@Override
void brew() {
System.out.println(“浸泡茶叶”);
}

@Override
void addCondiments() {
    System.out.println("添加柠檬");
}

}

// 测试代码
public class TemplatePatternExample {
public static void main(String[] args) {
System.out.println(“制作咖啡:”);
BeverageMaker coffee = new CoffeeMaker();
coffee.prepareBeverage();

    System.out.println("\n制作茶:");
    BeverageMaker tea = new TeaMaker();
    tea.prepareBeverage();
}

}

输出:

制作咖啡:
烧开水
冲泡咖啡
倒入杯子
添加糖和奶

制作茶:
烧开水
浸泡茶叶
倒入杯子
添加柠檬

模板模式的特点

  • 优点
  • 封装不变的算法骨架,复用公共代码,符合代码复用原则。
  • 子类只需实现特定步骤,降低开发复杂性。
  • 模板方法通常为 final,确保算法流程不可更改,增强一致性。
  • 符合开闭原则,新增行为只需添加新的子类。
  • 缺点
  • 每个具体实现都需要一个子类,如果变化较多,可能导致类数量增加。
  • 抽象模板类的设计需要仔细规划,抽象方法过多或过少都会影响灵活性。

使用场景

  1. 当需要定义一个固定的算法流程,但部分步骤需要子类自定义时:
  • 数据处理流程(如文件解析、数据导出)。
  • 游戏中的关卡加载流程(如初始化、加载资源、渲染)。
  • 业务流程(如订单处理、支付流程)。
  1. 需要统一行为框架但允许具体实现差异的场景:
  • 不同类型的报表生成。
  • 不同协议的网络通信处理。
  1. 希望通过复用公共代码减少重复开发的场景。

注意事项

  • 模板方法的控制:模板方法通常声明为 final,防止子类修改算法骨架。
  • 钩子方法:可以在抽象模板类中提供空实现或默认实现的方法(称为钩子方法),让子类选择是否覆盖。
  • 与策略模式的区别
  • 模板模式通过继承定义算法骨架,强调固定流程。
  • 策略模式通过组合动态选择算法,强调行为的可替换性。
  • 扩展性:设计抽象模板时,应尽量将变化点抽象为方法,方便子类扩展。

总结

模板模式通过在抽象类中定义算法骨架,将可变部分延迟到子类实现,实现了代码复用和行为一致性。它适用于固定流程但细节可变的场景,如流程控制、业务处理等。设计时需平衡抽象方法的粒度和数量,以确保系统的灵活性和可维护性。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注