加载中...
JavaScript设计模式 -- 8.模板方法模式
发表于:2021-06-06 | 分类: 前端

定义

模板方式是一种只需要继承就可以实现的简单的模式

模板由两个部分结构组成,第一个是抽象类,第二部分是具体的实现子类
通常在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺序。
子类通过继承这个抽象父类,也继承了算法框架,并且可以选择重写父类。

举个栗子 - Coffee or Tea

  1. 泡一杯咖啡

泡咖啡的步骤通常如下:
1)把水煮沸
2)用沸水冲咖啡
3)把咖啡倒进杯子
4)加糖或加奶

通过下面的代码我们就可以获得一杯咖啡

class Coffee {
  init() {
    inst.boilWater();
    inst.brewCoffeeGriends();
    inst.pourInCup();
    inst.addSugarAndMilk();
  }
  boilWater() {
    console.log("煮沸水");
  }

  brewCoffeeGriends() {
    console.log("用沸水冲咖啡");
  }

  pourInCup() {
    console.log("将咖啡倒进杯子");
  }

  addSugarAndMilk() {
    console.log("加糖或加奶");
  }
}

const inst = new Coffee();
inst.init();
  1. 泡一杯茶

泡茶的步骤通常如下:
1)把水煮沸
2)用沸水浸泡茶叶
3)把茶倒进杯子
4)加柠檬

class Tea {
  init() {
    this.boilWater();
    this.steepTeaBag();
    this.pourInCup();
    this.addLemon();
  }
  boilWater() {
    console.log("煮沸水");
  }

  steepTeaBag() {
    console.log("用沸水浸泡茶叶");
  }

  pourInCup() {
    console.log("把茶倒进杯子");
  }

  addLemon() {
    console.log("加柠檬");
  }
}
const inst = new Tea();
inst.init();

事实上,泡咖啡和泡茶的过程是大同小异的。我们可以发现,主要有以下几点不同:

原料不同。一个是咖啡,一个是茶叶,我们可以抽象成“饮料”
泡的方式不同,一个是冲泡,一个是浸泡。我们可以抽象为“泡”
加入的调料不同,一个是糖和牛奶,一个是柠檬。我们可以抽象为“调料”

经过抽象后,不管是泡咖啡还是泡茶,我们都抽象成为以下四个步骤:

1)把水煮沸
2)用沸水冲泡饮料
3)把饮料倒进杯子
4)在饮料中加入调料

所以,不管是冲泡还是浸泡,我们都可以给一个通用的方法 brew()。
同理,不管是糖还是牛奶还是柠檬,我们都可以称之 addCondiments()

class Beverage {
  boilWater() {
    console.log("把水煮沸");
  }

  brew() {
    throw new Error("子类必须重写brew方法");
  }

  pourInCup() {
    throw new Error("子类必须重写pourInCup方法");
  }

  addCondiments() {
    throw new Error("子类必须重写addCondiments方法");
  }
  init() {
    this.boilWater();
    this.brew();
    this.pourInCup();
    this.addCondiments();
  }
}

然后,我们可以创建 Coffee 和 Tea 子类

class Coffee extends Beverage {
  brew() {
    console.log("用沸水冲泡咖啡");
  }

  pourInCup() {
    console.log("吧咖啡倒进杯子");
  }

  addCondiments() {
    console.log("给咖啡加糖");
  }
}

const coffee = new Coffee();
coffee.init();

class Tea extends Beverage {
  brew() {
    console.log("用沸水浸泡茶");
  }

  pourInCup() {
    console.log("把茶倒进杯子");
  }

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

const tea = new Tea();
tea.init();

模板方法的应用场景

模板方法模式常被架构师用于搭建项目的框架,架构师定好了框架的骨架,
程序员继承框架的结构之后,负责往里面填空。

hook 方法

当某些子类有一些个性化的需求,比如这里,泡茶不想要加柠檬。
那么可以这样改写父类

class Beverage {
  // ....
  wantsAddCondiments() {
    return true;
  }
  init() {
    this.boilWater();
    this.brew();
    this.pourInCup();
    if (this.wantsAddCondiments()) this.addCondiments();
  }
}
class Tea extends Beverage {
  brew() {
    console.log("用沸水浸泡茶");
  }

  pourInCup() {
    console.log("把茶倒进杯子");
  }

  wantsAddCondiments() {
    return window.confirm("是否想加柠檬呢?");
  }

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

const tea = new Tea();
tea.init();
上一篇:
JavaScript设计模式 -- 7.组合模式
下一篇:
JavaScript设计模式 -- 设计原则
本文目录
本文目录