likes
comments
collection

js设计模式-模板方法模式

作者站长头像
站长
· 阅读数 23
定义

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

应用场景

当我们有一些平行的子类,各个子类之间有一些相同的行为,也有一些不同的行为,并且相同和不同的行为都混合在各个子类的实现中,这个时候我们可以将子类实现中相同的部分移到父类上,而将不同的部分留待子类来实现。

举个🌰

我们需要泡三种饮料,冲泡过程如下: 可以看到他们的第一步是一样的,并且实现过程很类似,这样我们可以将其中的公共部分提出来生成一个抽象父类,然后再通过子类对父类的继承获得公共方法,并且在子类中重写中间的不同步骤。

js设计模式-模板方法模式

提取的公共类实现如下:

js设计模式-模板方法模式

上代码
abstract class Beverage { // 父类
  public init() { // 父类中定义了子类的实现顺序
    this.boilWater()
    this.brew()
    this.pourInCup()
    if (this.customerWantsCondiments()) { // 在父类中控制子类不同的实现逻辑
      this.addCondiments()
    }
  }
  public boilWater() { // 公共方法
    console.log('把水煮沸')
  }
  public abstract brew():void; // 待子类实现的抽象方法
  public abstract pourInCup():void
  public abstract addCondiments():void
  public customerWantsCondiments() { // 子类可实现可不实现的公共方法,用来区分子类的不同行为
    return true
  }
}

export class Coffee extends Beverage { // coffee子类
  public brew(){
    console.log('用沸水冲泡咖啡')
  }
  public pourInCup() {
    console.log('把咖啡倒进杯子')
  }
  public addCondiments() {
    console.log('加糖和牛奶')
  }
}

export class Tea extends Beverage { //tea子类
  public brew(){
    console.log('用沸水浸泡茶叶')
  }
  public pourInCup() {
    console.log('把茶水倒进杯子')
  }
  public addCondiments() {
    console.log('加柠檬')
  }
}

export class CoffeeWithHook extends Coffee { //自助coffee子类
  customerWantsCondiments() {
    return window.confirm('需要加调料吗?')
  } 
}

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

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

const coffeeWithHook = new CoffeeWithHook()
coffeeWithHook.init()