设计模式之-模板模式

模板方法模式是一种只需使用继承就可以实现的非常简单的模式
它由两部分构成,1.抽象父类2.具体实现子类。通常在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有的执行顺序,子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法。

来看一个咖啡与茶的例子

javascript 复制代码
// 1.先泡一杯咖啡
        class Coffee {
            boilWater(){
                console.log('把水煮沸');
            }
            brewCoffeeGriends(){
                console.log('用沸水冲泡咖啡');
            }
            pourInCup(){
                console.log('把咖啡倒进杯子');
            }
            addSugarAndMilk(){
                console.log('加糖和牛奶');
            }
            init(){
                this.boilWater();
                this.brewCoffeeGriends();
                this.pourInCup();
                this.addSugarAndMilk();
            }
        }
        const coffee = new Coffee();
        coffee.init();

        //2.泡一壶茶
        class Tea {
            boilWater(){
                console.log('把水煮沸');
            }
            steepTeaBag(){
                console.log('用沸水浸泡茶叶');
            }
            pourInCup(){
                console.log('把茶水倒进杯子');
            }
            addLemon(){
                console.log('加柠檬');
            }
            init(){
                this.boilWater();
                this.steepTeaBag();
                this.pourInCup();
                this.addLemon();
            }
        }
        const tea = new Coffee();
        tea.init();

分离共同点

typescript 复制代码
// 让我们忘记最开始创建的Coffee类和Tea类,现在可以创建一个抽象父类来表示泡一杯饮料的整个过程。
abstract class Beverage {
  boilWater() {
    console.log("把水煮沸");
  }
  abstract brew(): void; // 抽象方法,由子类重写
  abstract pourInCup(): void; // 抽象方法,由子类重写
  abstract addCondiments(): void; // 抽象方法,由子类重写

  init() {
    this.boilWater();
    this.brew();
    this.pourInCup();
    this.addCondiments();
  }
}
// 现在来创建Coffee类和Tea类
class Coffee extends Beverage {
  brew(): void {
    console.log("用沸水冲泡咖啡");
  }
  pourInCup(): void {
    console.log("把咖啡倒进杯子");
  }
  addCondiments(): void {
    console.log("加糖和牛奶");
  }
}
class Tea extends Beverage {
  brew(): void {
    console.log("用沸水浸泡茶叶");
  }
  pourInCup(): void {
    console.log("把茶水倒进杯子");
  }
  addCondiments(): void {
    console.log("加柠檬");
  }
}
// 使用
const coffee = new Coffee();
coffee.init();
const tea = new Tea();
tea.init();

在上面的例子中,到底谁才是所谓的模版方法呢,答案是Beverage类中的init方法,该方法封装了子类算法框架,他作为一个算法模版,指导子类以何种顺序去执行那些方法,在init方法中算法内的每一个步骤都清楚地展示在我们面前。
这些算法框架在正常状态下是适用于大多数子类的,但如果有一些特别"个性"的子类呢?比如有一些客人喝咖啡不加调料(糖和牛奶),有什么半打可以让子类不受这个约束呢?那么钩子方法可以用来解决这个问题,放置钩子是隔离变化的一种常见手段。我们在父类中容易变化的地方放置钩子,钩子可以有一个默认的实现,究竟要不要"挂钩",这由子类自行决定。

typescript 复制代码
abstract class Beverage {
  boilWater() {
    console.log("把水煮沸");
  }
  abstract brew(): void; // 抽象方法,由子类重写
  abstract pourInCup(): void; // 抽象方法,由子类重写
  abstract addCondiments(): void; // 抽象方法,由子类重写

  customerWantsCondiments(){
    return true; // 默认需要调料
  }
  init() {
    this.boilWater();
    this.brew();
    this.pourInCup();
    if(this.customerWantsCondiments()){//如果挂钩返回true,则需要调料
        this.addCondiments();
    }
  }
}
// 现在来创建Coffee类和Tea类
class Coffee extends Beverage {
  brew(): void {
    console.log("用沸水冲泡咖啡");
  }
  pourInCup(): void {
    console.log("把咖啡倒进杯子");
  }
  addCondiments(): void {
    console.log("加糖和牛奶");
  }
   customerWantsCondiments(){
    return window.confirm('请问需要调料吗?')
  }
}
class Tea extends Beverage {
  brew(): void {
    console.log("用沸水浸泡茶叶");
  }
  pourInCup(): void {
    console.log("把茶水倒进杯子");
  }
  addCondiments(): void {
    console.log("加柠檬");
  }
}
// 使用
const coffee = new Coffee();
coffee.init();
const tea = new Tea();
tea.init();

非原创,来源于javascript设计模式与开发实践 -曾探

相关推荐
Carl_奕然2 小时前
【智能体】Agent的四种设计模式之:ReAct
人工智能·设计模式·语言模型
二哈赛车手3 小时前
新人笔记---多策略搭建策略执行链实现RAG检索后过滤
java·笔记·spring·设计模式·ai·策略模式
楼田莉子4 小时前
仿Muduo的高并发服务器:Channel模块与Poller模块
linux·服务器·c++·学习·设计模式
geovindu19 小时前
go: Strategy Pattern
开发语言·设计模式·golang·策略模式
嵌入式学习_force1 天前
02_state
设计模式·蓝牙
qcx231 天前
Warp源码深度解析(七):Token预算策略——双轨计费、上下文溢出与摘要压缩
人工智能·设计模式·rust·wrap
Cosolar2 天前
提示词工程面试题系列 - Zero-Shot Prompting 和 Few-Shot Prompting 的核心区别是什么?
人工智能·设计模式·架构
geovindu2 天前
go:Template Method Pattern
开发语言·后端·设计模式·golang·模板方法模式
钝挫力PROGRAMER2 天前
贫血模型的改进
java·开发语言·设计模式·架构
qcx232 天前
Warp源码深度解析(二):自研GPU UI框架——WarpUI的ECH模式与渲染管线
人工智能·ui·设计模式·rust