TypeScript中的模板方法模式
模板方法模式 (Template Method Pattern) 是一种使用应用很常见的行为型设计模式。它通过在基类中定义模板方法,子类通过覆盖特定步骤来完善具体过程。它通常用于处理有一致步骤的过程,但一些具体的步骤可以在子类中自定义。
模板方法模式的主要特点
- 封装固定的步骤,防止子类修改此步骤。
- 允许子类通过覆盖方法来自定义步骤细节。
- 增加代码的重用性,减少重复代码。
实现模板方法模式
我们通过一个食物制作的例子来实现模板方法模式:
abstract class FoodTemplate {
// 模板方法
public prepareFood(): void {
this.prepareIngredients();
this.cook();
this.serve();
}
// 抽象方法,需要子类实现
protected abstract prepareIngredients(): void;
protected abstract cook(): void;
// 共享方法,可选覆盖
protected serve(): void {
console.log("为客人装盘。");
}
}
// 实现具体的饭菜
class Pasta extends FoodTemplate {
protected prepareIngredients(): void {
console.log("准备面粉和番茄酱。");
}
protected cook(): void {
console.log("煮面条并配上番茄酱。");
}
}
class FriedRice extends FoodTemplate {
protected prepareIngredients(): void {
console.log("准备米饭和蔬菜。");
}
protected cook(): void {
console.log("炒饭配蔬菜。");
}
}
// 使用
const pasta = new Pasta();
pasta.prepareFood();
const friedRice = new FriedRice();
friedRice.prepareFood();
进一步优化
在模板方法中,我们可以通过加入选填方法 (Hook Method),使子类可选性地覆盖部分行为。
abstract class FoodTemplateWithHook {
public prepareFood(): void {
this.prepareIngredients();
this.cook();
if (this.needSauce()) {
this.addSauce();
}
this.serve();
}
protected abstract prepareIngredients(): void;
protected abstract cook(): void;
protected serve(): void {
console.log("为客人装盘。");
}
protected needSauce(): boolean {
return true;
}
protected addSauce(): void {
console.log("加入汤汁。");
}
}
class Noodles extends FoodTemplateWithHook {
protected prepareIngredients(): void {
console.log("准备鸡蛋面和蔬菜。");
}
protected cook(): void {
console.log("煮面条。");
}
protected needSauce(): boolean {
return false; // 这里选择不需要汤汁
}
}
const noodles = new Noodles();
noodles.prepareFood();
结论
模板方法模式在 TypeScript 中可以通过抽象类来实现,在基类中定义模板方法,允许子类自定义特定步骤,提高代码的重用性,同时限制了子类作出不适当的修改。