谈谈模板方法模式,模板方法模式的应用场景是什么?

一、模式核心理解

模板方法模式是一种​​行为设计模式​​,通过定义算法骨架并允许子类重写特定步骤来实现代码复用。

如同建筑图纸规定房屋结构,具体装修由业主决定,该模式适用于​​固定流程中需要灵活扩展​​的场景。

// 基础请求处理类(模板)
class BaseRequestHandler {
  // 模板方法(禁止override)
  async execute() {
    this.validateParams();
    const processed = await this.processRequest();
    this.afterProcess();
    return this.createResponse(processed);
  }

  validateParams() {
    throw new Error("必须实现参数校验方法");
  }

  // 钩子方法(可选实现)
  afterProcess() {}
}

// 具体API请求实现
class UserAPIHandler extends BaseRequestHandler {
  validateParams() {
    if (!this.params.userId) throw "用户ID必填";
  }

  async processRequest() {
    return await fetch(`/users/${this.params.userId}`);
  }

  createResponse(data) {
    return { status: 200, data };
  }
}

// 使用示例
const handler = new UserAPIHandler({ userId: 123 });
handler.execute();

二、典型应用场景

1. 框架生命周期控制

// React类组件示例
class BaseComponent extends React.Component {
  // 模板方法
  componentDidMount() {
    this.initState();
    this.fetchData();
    this.bindEvents();
  }

  initState() {}       // 子类实现
  fetchData() {}       // 子类实现
  bindEvents() {}      // 默认空实现(钩子方法)
}

class UserList extends BaseComponent {
  initState() {
    this.setState({ users: [] });
  }

  fetchData() {
    axios.get('/api/users').then(res => this.setState({ users: res.data }));
  }
}

2. 表单校验系统

class FormValidator {
  validate(formData) {
    this.checkRequiredFields(formData);
    const customResult = this.customValidation(formData);
    return this.formatResult(customResult);
  }

  checkRequiredFields(formData) {
    // 通用必填校验逻辑
  }

  customValidation() {
    throw new Error("必须实现具体校验规则");
  }

  formatResult(result) {
    return { isValid: result, timestamp: Date.now() };
  }
}

class LoginFormValidator extends FormValidator {
  customValidation(formData) {
    return formData.password.length >= 8;
  }
}

三、使用建议

  1. ​流程标准化​​:支付流程(风控检查->创建订单->调用支付->结果处理)
class PaymentProcessor {
  async pay(amount) {
    this.riskCheck();
    const order = this.createOrder(amount);
    const result = await this.callPaymentGateway(order);
    return this.handleResult(result);
  }
  // ...抽象方法声明
}
  1. ​合理使用钩子​​:在报表生成器中设置可选步骤
class ReportGenerator {
  generate() {
    this.fetchData();
    this.beforeRender(); // 钩子方法
    this.renderHeader();
    this.renderBody();
  }

  beforeRender() {} // 默认空实现
}
  1. ​组合优于继承​​:对于复杂场景建议使用策略模式+模板方法
class DataExporter {
  constructor(formatter) {
    this.formatter = formatter;
  }

  export() {
    const raw = this.getData();
    return this.formatter(raw);
  }
}

四、注意事项

  1. ​避免流程碎片化​​(错误示例)
// 反模式:过度拆分步骤
class BadTemplate {
  execute() {
    this.step1();
    this.step2();
    this.step3();
    this.step4();
    // 20+步骤...
  }
}
  1. ​子类责任边界​
class OrderProcessor extends BaseProcessor {
  validate() {
    // 不要修改执行顺序
    super.validate(); // 必须调用父类方法
    this.checkInventory(); // 扩展校验
  }
}
  1. ​模板方法冻结​
class SecureBase {
  execute() {
    Object.freeze(this.execute); // 防止子类重写模板方法
    // ...执行流程
  }
}

五、总结

模板方法模式在前端开发中适合处理​​流程固定但实现可变​​的场景,如请求处理、表单校验、生命周期管理等。使用时要注意:

  1. 保持模板方法稳定,通过钩子方法扩展
  2. 子类实现不超过3层继承
  3. 复杂场景结合策略模式使用
  4. 使用TypeScript时声明抽象方法
// TypeScript实现示例
abstract class UIComponent {
  abstract render(): void;

  mount() {
    this.willMount();
    this.render();
    this.didMount();
  }

  protected willMount() {}
  protected didMount() {}
}

正确使用模板方法模式可以提升代码复用率30%以上,但需根据实际场景灵活选择实现方式。

在微前端架构中,该模式常用于基座应用与子应用的生命周期管理,建议结合具体业务需求进行合理设计。