当前位置: 首页 > news >正文

设计模式-模板方法模式(Template Method)

设计模式-模板方法模式(Template Method)

    • 一、模板方法模式概述
      • 1.1 什么是模板方法模式
      • 1.2 简单实现模板方法模式
      • 1.3 使用模板方法模式的注意事项
    • 二、模板方法模式的用途
    • 三、模板方法模式实现方式
      • 3.1 抽象类中定义模板方法,子类实现具体方法。
      • 3.2 抽象类中定义模板方法,子类实现部分方法,父类提供默认实现。
      • 3.3 抽象类中定义多个模板方法,每个模板方法对应不同的算法流程。
      • 3.4 抽象类中定义带参数的模板方法,子类根据参数选择不同的算法流程。

一、模板方法模式概述

1.1 什么是模板方法模式

模板方法模式,也被称为模板模式,是一种行为型设计模式。它在一个抽象类中公开定义了执行其方法的模板,规定了算法的骨架。其主要特点是将一些步骤延迟到子类中,这些子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。

这种类型的设计模式主要解决了一些通用的方法在每一个子类都重新写了这一问题,其主要目的是将这些通用算法抽象出来。通过使用模板方法模式,子类可以在不改变算法结构的情况下,重新定义算法中的某些特定步骤。

例如,在建筑行业中,造房子的地基、走线、水管等步骤都是一样的,只有在建筑的后期才会有加壁橱加栅栏等差异。在这种情况下,可以使用模板方法模式来规划和设计建筑流程。另一个例子是西游记中的81难,这就是一个典型的顶层逻辑骨架。

1.2 简单实现模板方法模式

首先,创建一个抽象类AbstractClass,其中包含一个抽象方法templateMethod(),这个方法包含了算法的骨架。然后,创建两个子类ConcreteClassA和ConcreteClassB,分别实现了templateMethod()方法。

// 抽象类
public abstract class AbstractClass {// 抽象方法,包含算法的骨架public final void templateMethod() {step1();step2();step3();}// 具体步骤1protected abstract void step1();// 具体步骤2protected abstract void step2();// 具体步骤3protected abstract void step3();
}// 子类A
public class ConcreteClassA extends AbstractClass {@Overrideprotected void step1() {System.out.println("子类A执行步骤1");}@Overrideprotected void step2() {System.out.println("子类A执行步骤2");}@Overrideprotected void step3() {System.out.println("子类A执行步骤3");}
}// 子类B
public class ConcreteClassB extends AbstractClass {@Overrideprotected void step1() {System.out.println("子类B执行步骤1");}@Overrideprotected void step2() {System.out.println("子类B执行步骤2");}@Overrideprotected void step3() {System.out.println("子类B执行步骤3");}
}

最后,在客户端代码中,可以创建不同的子类对象,并调用它们的templateMethod()方法来执行算法

public class Client {public static void main(String[] args) {AbstractClass concreteClassA = new ConcreteClassA();concreteClassA.templateMethod();AbstractClass concreteClassB = new ConcreteClassB();concreteClassB.templateMethod();}
}

运行客户端代码,可以看到输出结果如下:

子类A执行步骤1
子类A执行步骤2
子类A执行步骤3
子类B执行步骤1
子类B执行步骤2
子类B执行步骤3

1.3 使用模板方法模式的注意事项

  • 1、抽象类应该定义算法的骨架,将一些步骤延迟到子类中实现。这些步骤应该是通用的,可以被不同的子类重写。

  • 2、抽象类中的抽象方法需要声明为final,防止被子类修改。

  • 3、抽象类可以包含一些具体的方法,这些方法可以在子类中被覆盖或直接调用。

  • 4、子类需要实现抽象类中的所有抽象方法,否则子类也必须声明为抽象类。

  • 5、客户端代码应该针对抽象类进行编程,而不是针对具体的子类。这样可以提高代码的可扩展性和可维护性。

  • 6、在模板方法模式中,子类可以根据需要对算法的某些特定步骤进行修改,但是整个算法的结构不应该被改变。

  • 7、模板方法模式适用于那些算法结构相对稳定,但某些步骤需要根据具体情况进行变化的场景。如果算法结构经常发生变化,那么使用策略模式可能更加合适。

二、模板方法模式的用途

模板方法模式,也被称为模板模式(Template Pattern),是一种行为型设计模式。它在一个抽象类中公开定义了执行其方法的模板,规定了算法的骨架。其主要特点是将一些步骤延迟到子类中实现,这些步骤可以是通用的,可以被不同的子类重写。

在Java编程语言中,模板方法模式被广泛应用。例如,在Servlet中,有一种叫做"processRequest"的方法,这个方法就是一个模板方法,定义了一系列的流程,如获取请求参数、调用service方法处理业务逻辑、返回响应结果等。具体的业务逻辑处理则由子类去实现。

此外,模板方法模式还常用于创建复杂的对象。比如在创建一个复杂的汽车对象时,这个汽车有很多部件和功能,有些部件和功能的创建和装配过程是相似的,而有些则是独特的。在这种情况下,就可以使用模板方法模式来定义一个汽车对象的创建和装配过程的骨架,然后让子类去实现具体的创建和装配过程。

总的来说,模板方法模式的优点在于提高代码复用性,增加扩展性,并且符合开闭原则。

三、模板方法模式实现方式

3.1 抽象类中定义模板方法,子类实现具体方法。

这是最常见的实现方式,也是最简单的实现方式。

// 定义一个抽象类
public abstract class Animal {// 定义一个模板方法public void makeSound() {// 默认实现System.out.println("动物发出声音");}
}// 定义一个子类,实现抽象类中的模板方法
public class Dog extends Animal {@Overridepublic void makeSound() {// 具体实现System.out.println("汪汪汪");}
}// 定义一个子类,实现抽象类中的模板方法
public class Cat extends Animal {@Overridepublic void makeSound() {// 具体实现System.out.println("喵喵喵");}
}// 测试代码
public class Main {public static void main(String[] args) {Animal dog = new Dog();dog.makeSound(); // 输出:汪汪汪Animal cat = new Cat();cat.makeSound(); // 输出:喵喵喵}
}

3.2 抽象类中定义模板方法,子类实现部分方法,父类提供默认实现。

这种方式可以使得子类更加灵活,可以根据需要选择是否覆盖父类的方法。
要实现抽象类中定义模板方法,子类实现部分方法,父类提供默认实现,可以按照以下步骤进行:

创建一个抽象类,包含一个抽象方法作为模板方法。
在抽象类中定义一个或多个默认实现的方法。
创建子类,继承抽象类,并实现抽象方法。
在子类中覆盖父类的默认实现方法。
以下是一个简单的示例:

// 抽象类
public abstract class Animal {// 模板方法public void makeSound() {System.out.println("动物发出声音");}// 默认实现方法public void eat() {System.out.println("动物吃东西");}
}// 子类
public class Dog extends Animal {// 实现抽象方法@Overridepublic void makeSound() {System.out.println("汪汪汪");}// 覆盖父类的默认实现方法@Overridepublic void eat() {System.out.println("狗狗吃骨头");}
}// 测试代码
public class Main {public static void main(String[] args) {Animal dog = new Dog();dog.makeSound(); // 输出:汪汪汪dog.eat(); // 输出:狗狗吃骨头}
}

3.3 抽象类中定义多个模板方法,每个模板方法对应不同的算法流程。

这种方式适用于有多种算法流程的场景,可以提高代码的可读性和可维护性。
要实现抽象类中定义带参数的模板方法,子类根据参数选择不同的算法流程,可以按照以下步骤进行:

  • 1、创建一个抽象类,包含一个带有参数的抽象方法作为模板方法。
  • 2、在抽象类中定义一个或多个默认实现的方法。
  • 3、创建子类,继承抽象类,并实现抽象方法。
  • 4、在子类的实现方法中,根据传入的参数选择不同的算法流程。
    以下是一个简单的示例:
// 抽象类
public abstract class AbstractClass {// 带参数的抽象方法作为模板方法public abstract void templateMethod(int param);// 默认实现的方法public void defaultMethod() {System.out.println("这是默认实现的方法");}
}// 子类
public class SubClass extends AbstractClass {// 实现抽象方法@Overridepublic void templateMethod(int param) {if (param > 0) {algorithmA();} else {algorithmB();}}// 根据参数选择不同的算法流程private void algorithmA() {System.out.println("执行算法A");}private void algorithmB() {System.out.println("执行算法B");}
}// 测试代码
public class Main {public static void main(String[] args) {SubClass subClass = new SubClass();subClass.templateMethod(1); // 输出:执行算法AsubClass.templateMethod(-1); // 输出:执行算法BsubClass.defaultMethod(); // 输出:这是默认实现的方法}
}

3.4 抽象类中定义带参数的模板方法,子类根据参数选择不同的算法流程。

这种方式适用于算法流程比较复杂的场景,可以提高代码的灵活性和扩展性。
要实现抽象类中定义带参数的模板方法,子类根据参数选择不同的算法流程,可以按照以下步骤进行:

  • 1、创建一个抽象类,包含一个带有参数的抽象方法作为模板方法。
  • 2、在抽象类中定义一个或多个默认实现的方法。
  • 3、创建子类,继承抽象类,并实现抽象方法。
  • 4、在子类的实现方法中,根据传入的参数选择不同的算法流程。
    以下是一个简单的示例:
// 抽象类
public abstract class AbstractClass {// 带参数的抽象方法作为模板方法public abstract void templateMethod(int param);// 默认实现的方法protected void defaultMethod() {System.out.println("这是默认实现的方法");}
}// 子类
public class SubClass extends AbstractClass {@Overridepublic void templateMethod(int param) {if (param > 0) {algorithmA();} else {algorithmB();}}private void algorithmA() {System.out.println("执行算法A");}private void algorithmB() {System.out.println("执行算法B");}
}// 测试代码
public class Main {public static void main(String[] args) {SubClass subClass = new SubClass();subClass.templateMethod(1); // 输出:执行算法AsubClass.templateMethod(-1); // 输出:执行算法B}
}

相关文章:

设计模式-模板方法模式(Template Method)

设计模式-模板方法模式(Template Method) 一、模板方法模式概述1.1 什么是模板方法模式1.2 简单实现模板方法模式1.3 使用模板方法模式的注意事项 二、模板方法模式的用途三、模板方法模式实现方式3.1 抽象类中定义模板方法,子类实现具体方法…...

远程登录Linux方法(Linux平台相互远程;Windows远程登录Linux、远程编码、文件传输;无法远程登录的问题解决;c程序的编译)

在实际使用Linux系统过程中我们不可避免的需要远程登录Linux,这是因为未来大家使用Linux服务器的时候你所对应的那台Linux服务器不一定提供界面(服务器可能在外地)。本篇将会介绍远程登录Linux的方法。 文章目录 1. SSH介绍2. Linux平台相互远程及文件传输2.1 Linux…...

macOS 13.6 及后续系统安装 Asahi Linux 将破坏引导

导读Asahi Linux 是一个致力于为 Apple Silicon 设备带来 Linux 支持的项目,日前有用户反馈称,若在相关设备上安装了 macOS 13.6-14,再安装 Asahi Linux ,就会导致系统引导失败,出现“黑屏”情况。 目前 Asahi Linux 项…...

Python武器库开发-flask篇之flask框架的安装(二十一)

Flask介绍 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进…...

【CASS精品教程】打开cass提示base.dcl未找到文件的解决办法

打开cass 7.1时提示base.dcl未找到文件的解决办法。 文章目录 一、问题描述二、解决办法 一、问题描述 系统上安装了cad2006cass7.1,cass软件可以正常打开,但是在使用屏幕菜单绘制地图时,选择一个工具,提示base.dcl未找到文件&am…...

[vim]Python编写插件学习笔记3 - 命令行参数

0 环境 Windows 11 22H2gVim82 (D:/ProgramFiles/Vim)Python311 (D:/ProgramFiles/Python311)Vundle v0.10.2 阅读本文前,需要先了解前文: 《[vim]Python 编写插件学习笔记1 - 开始》 《[vim]Python 编写插件学习笔记2 - 分离》 1 前提说明 由于本…...

【仙逆】王林400年晋升元婴,复仇藤化元杀尽藤姓,高老畏罪自裁

Hello,小伙伴们,我是小郑继续为大家深度解析国漫资讯。 深度爆料仙逆第10集剧情解析,高启明,缥缈宗的元婴初期老祖,一生潜心研究推演之术,洞察先机,乃是宗门之人的精神支柱。藤化元曾为寻找王林父母所在之…...

云原生实战课大纲

1. 云原生是什么 原生应用(java,pyrhon) 上云的过程应用上云遇到的问题1.微服务的拆分 微服务的访问关系应用的架构云原生适合什么样的人去学具备什么样的前提条件云原生要学习什么docker k8s devlops server mesh jks k8s监控吧自己的微服务部署上…...

数据湖架构

数据湖架构介绍 数据湖(Data Lake)是一个存储大量结构化和非结构化数据的集中式数据存储库。 与传统的数据仓库不同,数据湖采用扁平化结构,将数据存储在原始形式下,不需要进行预处理或转化。这使得数据湖能够同时支持…...

Zabbix 5.0部署(centos7+server+MySQL+Apache)

环境 系统IPZABBIX版本主机名centos7192.168.231.2195.0zabbix-server 安装zabbix 我选择版本是zabbix-5.0 zabbix的官网是Zabbix :: The Enterprise-Class Open Source Network Monitoring Solution 安装Zabbix软件源 rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/…...

YOLO改进系列之注意力机制(CloAttention模型介绍)

CloAttention来自清华大学的团队提出的一篇论文CloFormer,作者从频域编码的角度认为现有的轻量级视觉Transformer中,大多数方法都只关注设计稀疏注意力,来有效地处理低频全局信息,而使用相对简单的方法处理高频局部信息。很少有方…...

openssl+AES开发实例(linux)

文章目录 一、AES介绍二、AES原理三、AES开发实例 一、AES介绍 AES(Advanced Encryption Standard)是一种对称密钥加密标准,它是一种对称加密算法,意味着相同的密钥用于加密和解密数据。AES 是 NIST(美国国家标准与技…...

FreeRTOS源码阅读笔记3--queue.c

消息队列可以应用于发送不定长消息的场合,包括任务与任务间的消息交换,队列是 FreeRTOS 主要的任务间通讯方式,可以在任务与任务间、中断和任务间传送信息,发送到 队列的消息是通过拷贝方式实现的,这意味着队列存储…...

云原生Kubernetes系列 | 通过容器互联搭建wordpress博客系统

云原生Kubernetes系列 | 通过容器互联搭建wordpress博客系统 通过容器互联搭建一个wordpress博客系统。wordpress系统是需要连接到数据库上的,所以wordpress和mysql的镜像都是需要的。wordpress在创建过程中需要指定一些参数。创建mysql容器时需要把mysql的数据保存在宿主机本…...

java读取OPC DA数据---Utgard

java读取OPC DA数据—Utgard Utgard库已经过时,原作者早已删除库,建议使用OPC UA,兼容OPC DA。 下面讲解Utgard使用 C#和C都不用配置DCOM,直接调用函数 既然是非要用Java,那就别想太方便,需要配置DCOM(后…...

在 Android 上简单安全地登录——使用凭证管理器和密钥

我踏马很高兴地听说, Credential Manager的公开版本将于 11 月 1 日开始提供。Credential Manager 为 Android 带来了身份验证的未来,简化了用户登录应用程序和网站的方式,同时使其更加安全。 登录可能具有挑战性 - 密码经常使用&#xff0c…...

【Python】上市公司数据进行经典OLS回归实操

一、题目二、数据合并、清洗、描述性统计1、数据获取2、数据合并3、选择董监高薪酬作为解释变量的理论逻辑分析 三、多元回归模型的参数估计、结果展示与分析1、描述性统计分析2、剔除金融类上市公司3、对所有变量进行1%缩尾处理4、0-1标准化,所有解释变量5、绘制热…...

科研学习|科研软件——有序多分类Logistic回归的SPSS教程!

一、问题与数据 研究者想调查人们对“本国税收过高”的赞同程度:Strongly Disagree——非常不同意,用“0”表示;Disagree——不同意,用“1”表示;Agree--同意,用“2”表示;Strongly Agree--非常…...

微服务简单理解与快速搭建

分布式和微服务 含义 微服务架构 微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些服…...

QColorDialog开发实例

文章目录 一、QColorDialog基本用法:二、QColorDialog详解三、QColorDialog接口说明静态函数成员函数 四、QColorDialog代码开发实例 QColorDialog 是 Qt 框架中用于选择颜色的对话框类。它提供了一个用户友好的界面,允许用户选择颜色。以下是 QColorDi…...

Kerberos身份认证原理与实战排错指南

1. 为什么今天还要花时间搞懂 Kerberos?——一个被低估的“老协议”正在悄悄支撑着你的日常你每天登录公司内网查邮件、访问财务系统提交报销、用 Jenkins 构建代码、甚至在 Windows 域环境中打开一台同事的共享文件夹……这些看似顺滑的操作背后,大概率…...

对比 Token Plan 与按量计费在 Taotoken 平台上的成本体感差异

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比 Token Plan 与按量计费在 Taotoken 平台上的成本体感差异 对于个人开发者或项目管理者而言,在接入大模型服务时&a…...

Lindy自动化效率翻倍的秘密:从零搭建高可靠多步骤任务流的7步黄金流程

更多请点击: https://intelliparadigm.com 第一章:Lindy自动化效率翻倍的秘密:从零搭建高可靠多步骤任务流的7步黄金流程 Lindy自动化平台以“越久越可靠”为设计哲学,将经典软件工程原则与现代可观测性实践深度融合。其核心优势…...

在线文档协作工具选型必看:14款产品对比(2026版)

一、在线文档协作工具的概念解析及其核心功能 在线文档协作工具是基于云端的文档创建、编辑、共享与协同沟通平台,核心目标是让团队在同一份资料上“实时共同工作”,减少反复传文件、版本混乱与沟通成本。 企业常见的核心能力包括: 多人实…...

Lovable电商网站搭建:如何用不到3人技术团队,72小时内上线PCI-DSS合规MVP版本?

更多请点击: https://codechina.net 第一章:Lovable电商网站搭建 Lovable 是一个面向中小商户的轻量级电商解决方案,采用现代 Web 技术栈构建,强调可扩展性、用户体验与快速部署能力。本章将指导你从零开始搭建一个具备商品展示、…...

ComfyUI-Manager完全指南:掌握AI工作流管理的核心技术

ComfyUI-Manager完全指南:掌握AI工作流管理的核心技术 【免费下载链接】ComfyUI-Manager ComfyUI-Manager is an extension designed to enhance the usability of ComfyUI. It offers management functions to install, remove, disable, and enable various custo…...

国产麒麟系统上编译GDAL 3.2.1踩坑记:从PROJ6依赖缺失到Qt环境集成

麒麟系统GDAL 3.2.1编译实战:PROJ6依赖修复与Qt工程深度集成在国产操作系统生态中部署地理数据处理工具链,往往会遇到比常规Linux发行版更复杂的依赖问题。最近在麒麟系统上为北斗定位项目编译GDAL 3.2.1时,遭遇了经典的"PROJ 6 symbols…...

解锁你的音乐收藏:浏览器端音频解密完整指南

解锁你的音乐收藏:浏览器端音频解密完整指南 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库: 1. https://github.com/unlock-music/unlock-music ;2. https://git.unlock-music.dev/um/web 项目地址: https://gitcod…...

PDF差异对比神器diff-pdf:告别文档核对烦恼,提升工作效率的智能解决方案

PDF差异对比神器diff-pdf:告别文档核对烦恼,提升工作效率的智能解决方案 【免费下载链接】diff-pdf A simple tool for visually comparing two PDF files 项目地址: https://gitcode.com/gh_mirrors/di/diff-pdf 你是否曾在核对PDF文档时感到头疼…...

AFOAuth2Manager调试技巧:常见问题排查与解决方案

AFOAuth2Manager调试技巧:常见问题排查与解决方案 【免费下载链接】AFOAuth2Manager AFNetworking Extension for OAuth 2 Authentication 项目地址: https://gitcode.com/gh_mirrors/af/AFOAuth2Manager AFOAuth2Manager是AFNetworking的OAuth 2.0认证扩展库…...