常用设计模式:模板方法模式

引言

模板方法模式(Template Method Pattern)是一种行为型设计模式。它定义算法骨架,将具体步骤延迟到子类实现。适用于固定流程但部分步骤可变的情景,如游戏初始化或数据处理。

定义

  • 抽象类:定义模板方法(final方法)和抽象步骤。
  • 具体子类:实现抽象步骤。

优点:代码复用,易扩展。缺点:子类过多时复杂。
classDiagram class Beverage { +prepare(): void +boilWater(): void +pourInCup(): void +brew(): void abstract +addCondiments(): void abstract } class Coffee { +brew(): void +addCondiments(): void } class Tea { +brew(): void +addCondiments(): void } Beverage <|-- Coffee Beverage <|-- Tea

TypeScript 示例

假设实现饮料冲泡流程。

类实现

typescript 复制代码
// 抽象类
abstract class Beverage {
  // 模板方法
  prepare(): void {
    this.boilWater();
    this.brew();
    this.pourInCup();
    this.addCondiments();
  }

  boilWater(): void {
    console.log("煮沸水");
  }

  abstract brew(): void; // 抽象步骤

  pourInCup(): void {
    console.log("倒入杯中");
  }

  abstract addCondiments(): void; // 抽象步骤
}

// 具体子类:咖啡
class Coffee extends Beverage {
  brew(): void {
    console.log("冲泡咖啡");
  }

  addCondiments(): void {
    console.log("加糖和奶");
  }
}

// 具体子类:茶
class Tea extends Beverage {
  brew(): void {
    console.log("浸泡茶叶");
  }

  addCondiments(): void {
    console.log("加柠檬");
  }
}

// 使用
const coffee = new Coffee();
coffee.prepare(); // 输出:煮沸水 冲泡咖啡 倒入杯中 加糖和奶

const tea = new Tea();
tea.prepare(); // 输出:煮沸水 浸泡茶叶 倒入杯中 加柠檬

prepare() 是模板方法,固定流程。子类重写 brew()addCondiments(),不改整体结构。

函数式实现

typescript 复制代码
// ======================
// Step 1: 定义策略函数类型
// ======================

type BrewFunction = () => void;
type AddCondimentsFunction = () => void;

// ======================
// Step 2: 固定步骤函数
// ======================

const boilWater = (): void => {
  console.log("🔥 Boiling water...");
};

const pourInCup = (): void => {
  console.log("🥛 Pouring into cup...");
};

// ======================
// Step 3: 模板方法(高阶函数)
// ======================

const makeDrink =
  (brew: BrewFunction, addCondiments: AddCondimentsFunction) =>
  (): void => {
    console.log("\n🧪 Starting to make a drink...\n");

    boilWater();           // 固定
    brew();                // 可变
    pourInCup();           // 固定
    addCondiments();       // 可变

    console.log("\n✅ Drink is ready!\n");
  };

// ======================
// Step 4: 策略实现(不同饮料)
// ======================

// Coffee
const brewCoffee: BrewFunction = () => {
  console.log("☕ Brewing coffee grounds...");
};

const addSugarAndMilk: AddCondimentsFunction = () => {
  console.log("🍬 Adding sugar and milk...");
};

// Tea
const brewTea: BrewFunction = () => {
  console.log("🍵 Steeping the tea...");
};

const addLemon: AddCondimentsFunction = () => {
  console.log("🍋 Adding a slice of lemon...");
};

// ======================
// Step 5: 组合并执行
// ======================

const makeCoffee = makeDrink(brewCoffee, addSugarAndMilk);
makeCoffee();

const makeTea = makeDrink(brewTea, addLemon);
makeTea();

真实案例

下面列举了 3 个真实开源仓库,包含明确的"模板方法模式(Template Method Pattern)"逻辑。

Apache Kafka(Java)

Kafka 的 复制(Replica / Fetcher / LogCleaner)流程大量使用模板方法模式。

模板方法骨架,文件:AbstractFetcherThread.java

java 复制代码
public abstract class AbstractFetcherThread extends ShutdownableThread {
    @Override
    public void doWork() {
        Map<TopicPartition, FetchData> fetched = fetchData();  // 模板步骤
        processFetchedData(fetched);                           // 模板步骤
        maybeThrottle();
    }

    protected abstract Map<TopicPartition, FetchData> fetchData();
    protected abstract void processFetchedData(Map<TopicPartition, FetchData> fetched);
}

子类实现步骤,示例:ReplicaFetcherThread.java

java 复制代码
@Override
protected Map<TopicPartition, FetchData> fetchData() {
    // 从 leader 拉取日志
}

@Override
protected void processFetchedData(Map<TopicPartition, FetchData> fetched) {
    // 写入本地日志副本
}
  • doWork() 是固定流程(骨架)
  • fetchData()、processFetchedData() 由子类决定

Spring Framework / Spring AOP

Spring AOP 的拦截器链实现中大量使用模板方法结构。

模板方法骨架,文件:AbstractPlatformTransactionManager.java

java 复制代码
public final TransactionStatus getTransaction(TransactionDefinition definition) {
    Object transaction = doGetTransaction();            // 模板步骤
    boolean newTx = shouldStartTransaction(...);      
    if (newTx) {
        doBegin(transaction, definition);               // 模板步骤
    }
    return prepareTransactionStatus(...);
}

protected abstract Object doGetTransaction();
protected abstract void doBegin(Object transaction, TransactionDefinition definition);

子类实现步骤,示例:DataSourceTransactionManager.java

java 复制代码
@Override
protected Object doGetTransaction() {
    return new DataSourceTransactionObject();
}

@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
    // 开启 JDBC 事务
}
  • getTransaction() 定义统一事务开启流程
  • 某些步骤由子类实现(JDBC, JPA, Hibernate 都不一样)

Medusa.js

Medusa 是一个基于 TypeScript 的电商框架,批量任务、支付、库存策略等通过抽象基类强制子类实现步骤。

模板方法骨架,文件:AbstractBatchJobStrategy.ts

typescript 复制代码
export abstract class AbstractBatchJobStrategy {
  async prepareBatchJob(batchJob: BatchJob): Promise<void> {
    await this.preProcessBatchJob(batchJob);   // 模板步骤
    await this.processJob(batchJob);           // 模板步骤
    await this.postProcessBatchJob(batchJob);  // 模板步骤
  }

  protected abstract preProcessBatchJob(job: BatchJob): Promise<void>;
  protected abstract processJob(job: BatchJob): Promise<void>;
  protected abstract postProcessBatchJob(job: BatchJob): Promise<void>;
}

子类实现步骤,示例:ProductImportStrategy.ts

typescript 复制代码
export class ProductImportStrategy extends AbstractBatchJobStrategy {
  protected async preProcessBatchJob(job) { ... }
  protected async processJob(job) { ... }
  protected async postProcessBatchJob(job) { ... }
}
  • 基类定义"批处理任务生命周期流程"
  • 子类完成具体逻辑

结语

模板方法模式提升代码可维护性,适用于框架设计。

相关推荐
繁华似锦respect6 小时前
C++ unordered_map 底层实现与详细使用指南
linux·开发语言·c++·网络协议·设计模式·哈希算法·散列表
繁华似锦respect12 小时前
HTTPS 中 TLS 协议详细过程 + 数字证书/签名深度解析
开发语言·c++·网络协议·http·单例模式·设计模式·https
数智研发说13 小时前
智汇电器携手鼎捷PLM:从“制造”迈向“智造”,构建高效协同研发新范式
大数据·人工智能·设计模式·重构·制造·设计规范
繁华似锦respect14 小时前
Linux - KCP 协议深度解析:原理、与 TCP/UDP 的对比及应用场景
linux·tcp/ip·观察者模式·设计模式·udp
太阳以西阿14 小时前
【设计模式03】命令设计模式(行为型设计模式)
设计模式
太阳以西阿14 小时前
【设计模式02】策略设计模式(行为型设计模式)
设计模式
雨中飘荡的记忆15 小时前
设计模式之享元模式详解
java·设计模式·享元模式
Blossom.11815 小时前
基于多智能体协作的AIGC内容风控系统:从单点检测到可解释裁决链
人工智能·python·深度学习·机器学习·设计模式·aigc·transformer
Jomurphys15 小时前
设计模式 - 责任链模式 Chain of Responsibility Pattern
android·设计模式·责任链模式
雨中飘荡的记忆15 小时前
设计模式之桥接模式详解
设计模式·桥接模式