TypeScript 设计模式之【模板方法模式】

news2024/11/17 17:44:14

文章目录

  • 模板方法模式:制作美味咖啡的标准流程
  • 模板方法模式的奥秘
    • 模板方法模式有什么利与弊?
    • 如何使用模板方法模式来优化你的系统
    • 代码实现案例
    • 模板方法模式的主要优点
    • 模板方法模式的主要缺点
    • 模板方法模式的适用场景
    • 总结

在这里插入图片描述

模板方法模式:制作美味咖啡的标准流程

当你走进一家咖啡店,不论点什么种类的咖啡,制作过程都遵循一定的步骤: 煮水、冲泡、倒入杯中、加入调料。这个看似简单的咖啡制作流程,实际上诠释了模板方法模式的精髓。

我们经常遇到一些操作的步骤是固定的,每个步骤的具体实现可能不同的情况。模板方法模式就像这个咖啡制作流程,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。这种模式让子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤!

模板方法模式的奥秘

模板方法模式就像一个"标准操作手册",它在一个方法中定义了一个算法的骨架,将一些步骤的实现延迟到子类中。通过这种方式,你可以让子类在不改变算法结构的情况下,重新定义算法中的某些步骤,使得系统更加灵活和可扩展。

模板方法模式有什么利与弊?

模板方法模式的优点是它提供了一种代码复用的技术,将公共行为放在父类中,而将具体的实现放在子类中。它实现了反向控制,子类可以决定如何实现算法中的某些步骤。缺点是每个不同的实现都需要一个子类,这可能会导致类的数量增加。

如何使用模板方法模式来优化你的系统

模板方法模式涉及角色

  • 抽象类(AbstractClass): 定义抽象的原语操作,具体的子类将重定义它们以实现一个算法的各个步骤
  • 具体类(ConcreteClass): 实现原语操作以完成算法中与特定子类相关的步骤

模板方法模式步骤

  1. 创建一个抽象类,定义一个模板方法和一些抽象方法
  2. 在模板方法中定义算法的骨架,调用抽象方法
  3. 创建具体子类,实现抽象方法
  4. 客户端通过具体子类来使用算法

选择合适的模板方法模式,你就能轻松地管理算法的结构,让系统变得更加灵活和可维护!

代码实现案例

// 抽象类- 咖啡机
abstract class CoffeeMaker {
  // 做咖啡
  makeCoffee(): void {
    // 煮水
    this.boilWater();
    // 冲泡
    this.brewCoffeeGrounds();
    // 倒入杯中
    this.pourInCup();
    // 加入调料
    this.addCondiments();
  }

  // 具体方法
  private boilWater(): void {
    console.log("煮沸水");
  }

  private pourInCup(): void {
    console.log("将咖啡倒入杯中");
  }

  // 抽象方法
  protected abstract brewCoffeeGrounds(): void;
  protected abstract addCondiments(): void;
}

// 具体类 - 美式咖啡
class AmericanoCoffee extends CoffeeMaker {
  protected brewCoffeeGrounds(): void {
    console.log("用沸水冲泡咖啡粉");
  }

  protected addCondiments(): void {
    console.log("加入少量热水");
  }
}

// 具体类 - 拿铁咖啡
class LatteCoffee extends CoffeeMaker {
  protected brewCoffeeGrounds(): void {
    console.log("用沸水冲泡浓缩咖啡");
  }

  protected addCondiments(): void {
    console.log("加入蒸煮牛奶和奶泡");
  }
}

// 客户端代码
console.log("制作美式咖啡:");
const americano = new AmericanoCoffee();
americano.makeCoffee();

console.log("\n制作拿铁咖啡:");
const latte = new LatteCoffee();
latte.makeCoffee();

// 输出
// 制作美式咖啡:
// 煮沸水
// 用沸水冲泡咖啡粉
// 将咖啡倒入杯中
// 加入少量热水

// 制作拿铁咖啡:
// 煮沸水
// 用沸水冲泡浓缩咖啡
// 将咖啡倒入杯中
// 加入蒸煮牛奶和奶泡

在这里插入图片描述

模板方法模式的主要优点

  1. 封装不变部分,扩展可变部分: 把不变的行为搬移到超类,去除子类中的重复代码
  2. 提供了一个很好的代码复用平台: 所有的子类可以共享父类中的代码
  3. 行为由父类控制,子类实现: 基本方法是由子类实现的,因此可以通过子类来定制行为
  4. 提高代码复用性: 将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中

模板方法模式的主要缺点

  1. 每一个不同的实现都需要一个子类: 这会导致类的个数增加,使得系统更加庞大
  2. 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果: 这导致一种反向的控制结构
  3. 模板方法中的步骤越多,其维护就可能越困难

模板方法模式的适用场景

  1. 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现
  2. 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复
  3. 控制子类扩展: 模板方法只在特定点调用"hook"操作,这样就只允许在这些点进行扩展

总结

模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。模板方法模式通过将算法的结构定义在父类中,而将一些特定步骤的实现延迟到子类中,实现了代码复用和灵活性的平衡。这种模式提高了代码的复用性和扩展性,同时也提高了代码的可读性和可维护性。合理使用模板方法模式,可以让你的代码结构更加清晰,更易于理解和维护。

喜欢的话就点个赞 ❤️,关注一下吧,有问题也欢迎讨论指教。感谢大家!!!

下期预告: TypeScript 设计模式之【访问者模式】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2176403.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode讲解篇之15. 三数之和

文章目录 题目描述题解思路题解代码 题目描述 题解思路 这道题如果我们直接使用三层循环暴力搜索,时间复杂度是O(n3),大概率会超时 那还有更优解吗,答案是绝对的,查询搜索想要优化,就要思考如何进行排除法加速搜索过…

【2023工业3D异常检测文献】基于混合融合的多模态工业异常检测方法Multi-3D-Memory (M3DM)

Multimodal Industrial Anomaly Detection via Hybrid Fusion 1、Background 随着3D传感器的发展,最近发布了具有2D图像和3D点云数据的MVTec-3D AD数据集,促进了多模态工业异常检测的研究。 无监督异常检测的核心思想是找出正常表示与异常之间的差异。…

爵士编曲:walking bass写法

写法 经常会出现在爵士、布鲁斯或者相关的衍生以及融合风格。 特征 1.基础形态是一拍一下顺着和弦音上行或者下行 2.和弦连接处可尝试凑级进” 3.注意和弦起始的第一拍要落在根音 4.音符可以八度跳进 5.加入半音经过音 6.加入Swing律动 还可以在一拍一下的基础上 7.加入音阶进一…

新160个crackme - 068-figugegl.3

运行分析 需破解Name和Serial有指定Name或Serial长度 PE分析 LCC-Win32编写的C语言程序,32位,无壳 静态分析&动态调试 ida找到可以字符串,双击进入 程序比较简单,直接静态分析,注释如上,逻辑如下&#…

FPGA实现PCIE视频采集转HDMI输出,基于XDMA中断架构,提供3套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的PCIE方案 3、PCIE基础知识扫描4、工程详细设计方案工程设计原理框图电脑端视频QT上位机XDMA配置及使用XDMA中断模块FDMA图像缓存Native视频时序生成RGB转HDMI输出模块Windows版本XDMA驱动安装Linux版本XDMA驱动安装工程源…

【Python】Mininet:网络虚拟化的利器

在当今网络技术迅速发展的背景下,网络虚拟化技术得到了广泛应用。Mininet 是一个轻量级的网络虚拟化工具,它使得用户能够在一台物理主机上创建一个完整的网络环境。这对于网络研究、教学、原型设计等场景都具有重要意义。Mininet 提供了简单的命令行接口…

【Python】bilibili实现批量发送弹幕功能

首先在直播间拿到发送弹幕的请求信息: 填写这里的信息: 在这里: 输入房间号,进行爆破: 效果如下: 代码如下: import random import time import requests from tkinter import *# 弹幕…

MySQL --事务

文章目录 1.什么是事务1.1为什么会出现事务1.2 事务的版本支持1.3 事务提交方式1.4事务常见操作方式1.4.1正常演示 - 证明事务的开始与回滚1.4.2非正常演示1 - 证明未commit,客户端崩溃,MySQL自动会回滚(隔离级别设置为读未提交)1…

grafana加载缓慢解决方案

背景 目前随着数据和图表的逐渐增多,Grafana 页面加载速度明显变慢,严重影响了用户体验,几次都有骂娘的冲动.,因此我们需要对 Grafana 进行优化,以提升加载性能。 对于速度优化,我们可以从以下方面进行入…

小程序-使用npm包

小程序对 npm 的支持与限制 目前,小程序中已经支持使用 npm 安装第三方包,从而来提高小程序的开发效率。但是,在小程序中使用 npm 包有如下 3 个限制: 不支持依赖于 Node.js 内置库的包不支持依赖于浏览器内置对象的包不支持依赖…

2015年国赛高教杯数学建模B题互联网+时代的出租车资源配置解题全过程文档及程序

2015年国赛高教杯数学建模 B题 互联网时代的出租车资源配置 出租车是市民出行的重要交通工具之一,“打车难”是人们关注的一个社会热点问题。随着“互联网”时代的到来,有多家公司依托移动互联网建立了打车软件服务平台,实现了乘客与出租车司…

在VM虚拟机上进行磁盘扩容

将/dev/mapper/ol-root从100G扩容到105G 初始状态的/dev/mapper/ol-root分配了100G 在VM上新增一个5G的物理硬盘 创建PV并纳入VG 对原本的LV扩容 扩大文件系统 完成。

vue框架学习 -- 日历控件 FullCalendar 使用总结

最近在项目中要实现日期排班的功能,正好要用到日历视图的控件,经过对比发现,vue 中 使用 FullCalendar 可以实现相关需求,下面对使用过程做一个总结。 一. 引入 FullCalendar 控件 package.json 中添加相关依赖 "dependen…

无人机专业实操重要性凸显,组装、调试、改装技术详解

无人机专业的实操性在当今技术飞速发展的背景下显得尤为重要,这不仅体现在无人机的日常应用上,还贯穿于无人机的组装、调试及改装等关键环节中。以下是对这些技术环节的详细解析: 一、无人机组装技术 无人机的组装是无人机技术的基础&#x…

828华为云征文|使用sysbench对Flexus X实例对mysql进行性能测评

目录 一、Flexus X实例概述 1.1 Flexus X实例 1.2 在mysql方面的优势 二、在服务器上安装MySQL 2.1 在宝塔上安装docker 2.2 使用宝塔安装mysql 2.3 准备测试数据库和数据库表 三、安装sysbench并进行性能测试 3.1 使用yum命令sysbench 3.2 运行 sysbench 并进行性能测…

Jumpserver堡垒机应用部署案例

本案例主要讲述了如何安装Jumpserver堡垒机应用,以及使用Jumpserver堡垒机对接OpenStack平台进行管理 一、OpenStack平台对接堡垒机 案例准备 1.规划节点 IP 主机名 节点 192.168.20.21 controller OpenStack Controller节点 192.168.20.22 jumpserver O…

0基础跟德姆(dom)一起学AI 机器学习02-KNN算法

【理解】KNN算法思想 K-近邻算法(K Nearest Neighbor,简称KNN)。比如:根据你的“邻居”来推断出你的类别 KNN算法思想:如果一个样本在特征空间中的 k 个最相似的样本中的大多数属于某一个类别,则该样本也属…

从事人工智能学习Python还是学习C++?

人工智能(Artificial Intelligence,简称AI)是当今科技领域最热门的研究方向之一。AI 涉及多个学科和技术,特别是机器学习、神经网络、深度学习等技术的应用。在AI的开发过程中,编程语言的选择对于开发效率和项目实现至…

戴尔电脑怎么开启vt虚拟化_戴尔电脑新旧机型开启vt虚拟化教程

最近使用戴尔电脑的小伙伴们问我,戴尔电脑怎么开启vt虚拟。大多数可以在Bios中开启vt虚拟化技术,当CPU支持VT-x虚拟化技术,有些电脑会自动开启VT-x虚拟化技术功能。而大部分的电脑则需要在Bios Setup界面中,手动进行设置&#xff…

C++ | Leetcode C++题解之第443题压缩字符串

题目&#xff1a; 题解&#xff1a; class Solution { public:int compress(vector<char>& chars) {int n chars.size();int write 0, left 0;for (int read 0; read < n; read) {if (read n - 1 || chars[read] ! chars[read 1]) {chars[write] chars[re…