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

【软件设计模式之模板方法模式】

文章目录

  • 前言
  • 一、什么是模板方法模式?
  • 二、模板方法模式的结构
    • 1. 抽象类定义
    • 2. 具体实现
  • 三、模板方法模式的应用场景
    • 1. 算法重用
    • 2. 操作中的固定步骤
    • 3. 扩展框架的功能
    • 4. 提供回调方法
    • 5. 遵循开闭原则
  • 四、模板方法模式的优缺点
    • 1. 优点
      • 代码复用
      • 扩展性好
      • 符合开闭原则
    • 2. 缺点
      • 可能导致类的数量增加
      • 增加了系统的复杂度
  • 五、实战案例
    • 抽象类定义
    • 具体实现
      • 文本帖子
      • 图片帖子
      • 视频帖子
    • 使用示例

前言

模板方法模式是一种基于继承的设计模式。它的核心在于定义一个算法的框架,同时允许子类在不改变算法整体结构的情况下重写算法的某些特定步骤。这种方式不仅保证了算法步骤的一致性,而且提供了足够的灵活性,以适应不同的情境需求。

一、什么是模板方法模式?

模板方法模式是一种行为设计模式,这种模式的主要目的是定义一个操作中的算法骨架,并将具体的实施细节延迟到子类中。这样做的主要优势在于算法的结构可以在不改变的情况下,在子类中重新定义某些特定的步骤。

具体来说,模板方法模式通常涉及两个主要部分:一个抽象类和一个或多个具体实现。抽象类定义了算法的框架和执行算法的方法,这个方法称为模板方法。它包括一系列定义良好的步骤,其中一些步骤是抽象的,留给子类来实现。这种设计允许模板方法固定算法的结构,确保按照特定顺序执行步骤,同时提供足够的灵活性来让子类实现具体的行为。

这种模式在软件开发中非常有用,尤其是当多个类中的算法有共同的部分但在某些方面又有所不同时。通过模板方法模式,可以最大化地重用代码,减少冗余,并提高系统的可维护性。此外,由于它遵循了开闭原则(即对扩展开放,对修改封闭),因此有助于创建灵活且可扩展的系统。

二、模板方法模式的结构

模板方法模式的结构主要包括两个核心部分:抽象类定义和具体类实现。这种结构允许算法的步骤在抽象层面上被定义,同时提供灵活性,以便在具体类中定制这些步骤的实现。下面是模板方法模式的详细结构说明:

1. 抽象类定义

在模板方法模式中,抽象类定义了执行算法的模板方法。这个模板方法设置了一个算法的基本框架,指定了算法的骨架和执行的步骤序列。

abstract class AbstractClass {public final void templateMethod() {primitiveOperation1();primitiveOperation2();concreteOperation();hook();}// 可以定义一些具体方法final void concreteOperation() {// 这里可以有一些默认的实现}// 定义一些抽象方法,留给子类实现abstract void primitiveOperation1();abstract void primitiveOperation2();// 钩子方法,子类可以视情况决定是否覆盖它void hook() {}// ... 其他方法定义 ...
}

在这个抽象类中,templateMethod 是一个模板方法,它定义了算法的框架。primitiveOperation1primitiveOperation2 是抽象方法,留给子类实现具体的功能。concreteOperation 是一个具体方法,提供了默认的实现。hook 是一个钩子方法,它提供了一个扩展点,子类可以选择性地覆盖它以提供特定的行为。

2. 具体实现

具体类继承自抽象类并实现其抽象方法,提供算法步骤的具体实现。这样,不同的具体类可以以不同的方式实现这些步骤,而算法的结构仍由抽象类中的模板方法控制。

class ConcreteClass extends AbstractClass {@Overrideprotected void primitiveOperation1() {// 具体的实现1}@Overrideprotected void primitiveOperation2() {// 具体的实现2}// 子类可以选择覆盖钩子方法@Overridevoid hook() {// 特定于子类的钩子方法实现}// ... 其他方法实现 ...
}

在这个具体类中,primitiveOperation1primitiveOperation2 提供了抽象方法的具体实现,而可选的 hook 方法允许在算法的特定点进行微调。通过这种方式,模板方法模式使得算法的结构固定下来,同时又能在子类中提供足够的灵活性来实现具体的行为。

三、模板方法模式的应用场景

1. 算法重用

当多个类中的算法有共同的行为但在某些步骤上需要不同的实现时,模板方法模式非常有用。例如,在数据处理应用中,多个数据解析器可能共享相同的数据加载和清洗步骤,但在数据解析的步骤上各不相同。通过模板方法模式,可以重用公共步骤的代码,同时允许每个解析器定制其特定的解析逻辑。

2. 操作中的固定步骤

在某些操作中,步骤的顺序是固定的,但每个步骤的具体实现可能会有所不同。例如,在构建工具中,构建过程(编译、链接、打包等)的步骤是固定的,但针对不同类型的项目(如Java项目、C++项目)这些步骤的具体实现会有所不同。模板方法模式允许定义一个固定的操作流程,同时提供自定义这些步骤的能力。

3. 扩展框架的功能

在框架设计中,模板方法模式可用于定义框架的核心流程,同时允许用户通过继承来扩展框架的功能。例如,一个Web框架可能会定义请求处理的基本流程,而允许用户通过重写特定方法来自定义请求的预处理、处理和后处理逻辑。

4. 提供回调方法

在需要为特定事件或条件提供回调方法的场景中,模板方法模式可以非常有效。例如,在图形用户界面(GUI)库中,可以使用模板方法来定义事件处理的基本结构(如点击事件),同时允许用户通过重写方法来提供特定的事件处理逻辑。

5. 遵循开闭原则

当需要设计遵循开闭原则的系统时,模板方法模式是一个很好的选择。这种模式允许系统在不修改现有代码的情况下,通过扩展新的子类来增加新的行为。

四、模板方法模式的优缺点

模板方法模式是一种在软件设计中常用的模式,它具有一些显著的优点,但也存在一些缺点。理解这些优缺点有助于更好地决定何时使用此模式。

1. 优点

代码复用

  • 标准化流程: 模板方法模式允许在抽象类中定义标准化的流程或算法框架,减少了重复代码。
  • 维护性: 由于核心算法在一个地方定义和维护,所以当核心流程变化时,只需修改抽象类。

扩展性好

  • 灵活性: 通过在子类中实现抽象方法,可以在不修改现有代码的情况下扩展功能。
  • 自定义: 用户可以根据需求自定义特定的步骤,提高了模式的适用性。

符合开闭原则

  • 开闭原则: 模板方法模式很好地遵循了开闭原则,即对扩展开放,对修改封闭,有利于构建稳定且灵活的系统。

2. 缺点

可能导致类的数量增加

  • 类膨胀: 如果有许多稍微不同的算法变种,可能导致子类数量迅速增加。
  • 管理难度: 随着子类数量的增加,管理和维护这些类变得更加困难。

增加了系统的复杂度

  • 理解难度: 对于新开发人员来说,理解整个框架的流程和扩展点可能比较困难。
  • 紧密耦合: 模板方法模式通常意味着子类与抽象类之间的紧密耦合,这可能限制了子类的使用场景。

五、实战案例

假设我们正在开发一个简化的社交媒体应用,其中包括不同类型的帖子发布流程,比如文本帖子、图片帖子和视频帖子。尽管每种帖子的发布细节不同,但它们都遵循相同的基本流程:准备内容、格式化内容、发布到平台。可以使用模板方法模式来实现这一功能。

抽象类定义

定义一个抽象类 SocialMediaPost,它包含发布帖子的模板方法以及几个抽象方法,这些抽象方法将在子类中具体实现。

abstract class SocialMediaPost {// 模板方法定义发布流程public final void publishPost() {prepareContent();formatContent();postToPlatform();}// 准备内容的步骤abstract void prepareContent();// 格式化内容的步骤abstract void formatContent();// 发布到平台的步骤abstract void postToPlatform();
}

具体实现

创建几个具体的类来实现不同类型的帖子。

文本帖子

class TextPost extends SocialMediaPost {@Overridevoid prepareContent() {System.out.println("Preparing text content...");}@Overridevoid formatContent() {System.out.println("Formatting text content...");}@Overridevoid postToPlatform() {System.out.println("Posting text content to platform...");}
}

图片帖子

class ImagePost extends SocialMediaPost {@Overridevoid prepareContent() {System.out.println("Preparing image content...");}@Overridevoid formatContent() {System.out.println("Formatting image content...");}@Overridevoid postToPlatform() {System.out.println("Posting image content to platform...");}
}

视频帖子

class VideoPost extends SocialMediaPost {@Overridevoid prepareContent() {System.out.println("Preparing video content...");}@Overridevoid formatContent() {System.out.println("Formatting video content...");}@Overridevoid postToPlatform() {System.out.println("Posting video content to platform...");}
}

使用示例

在应用程序中,我们可以根据需要创建不同类型的帖子,并调用其 publishPost 方法来发布。

public class Main {public static void main(String[] args) {SocialMediaPost textPost = new TextPost();textPost.publishPost(); // 发布文本帖子SocialMediaPost imagePost = new ImagePost();imagePost.publishPost(); // 发布图片帖子SocialMediaPost videoPost = new VideoPost();videoPost.publishPost(); // 发布视频帖子}
}

在这个实战案例中,模板方法模式使得我们能够定义发布帖子的基本流程,同时允许在不同类型的帖子中定制内容准备、格式化和发布的具体细节。这样不仅保证了流程的一致性,而且提供了足够的灵活性来处理各种类型的帖子。

相关文章:

【软件设计模式之模板方法模式】

文章目录 前言一、什么是模板方法模式?二、模板方法模式的结构1. 抽象类定义2. 具体实现 三、模板方法模式的应用场景1. 算法重用2. 操作中的固定步骤3. 扩展框架的功能4. 提供回调方法5. 遵循开闭原则 四、模板方法模式的优缺点1. 优点代码复用扩展性好符合开闭原则…...

Spring Boot项目怎么对System.setProperty(key, value)设置的属性进行读取加解密

一、前言 之前我写过一篇文章使用SM4国密加密算法对Spring Boot项目数据库连接信息以及yaml文件配置属性进行加密配置(读取时自动解密),对Spring Boot项目的属性读取时进行加解密,但是没有说明对System.setProperty(key, value)设…...

Linux理解

VMware安装Linux安装 目录 VMware安装Linux安装 1.1 什么是Linux 1.2 为什么要学Linux 1.3 学完Linux能干什么 2.1 主流操作系统 2.2 Linux系统版本 VMware安装Linux安装 1.1 什么是Linux Linux是一套免费使用和自由传播的操作系统。 1.2 为什么要学Linux 1). 企业用人…...

常用芯片学习——YC688语音芯片

YC688 广州语创公司语音芯片 使用说明 YC688是一款工业级的MP3语音芯片 ,完美的集成了MP3、WAV的硬解码。支持SPI-Flash、TF卡、U盘三种存储设备。可通过电脑直接更新SPI-Flash的内容,无需上位机软件。通过简单的串口指令即可完成三种存储设备的音频插…...

C语言:指针的进阶讲解

目录 1. 二级指针 1.1 二级指针是什么? 1.2 二级指针的作用 2. 一维数组和二维数组的本质 3. 指针数组 4. 数组指针 5. 函数指针 6. typedef的使用 7. 函数指针数组 7.1 转移表 1. 二级指针 如果了解了一级指针,那二级指针也是可以很好的理解…...

基于SSM的车位租赁系统(有报告)。Javaee项目。ssm项目。

演示视频: 基于SSM的车位租赁系统(有报告)。Javaee项目。ssm项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring Spri…...

Java pyhon C C++ R JS 主流语言的区别-03

以下是对这几种语言的数据类型进行简要归纳: Java的数据类型: 基本数据类型:包括整数类型(byte、short、int、long)、浮点数类型(float、double)、字符类型(char)和布尔…...

5 buuctf解题

命令执行 [BJDCTF2020]EasySearch1 打开题目 尝试弱口令&#xff0c;发现没有用 扫描一下后台&#xff0c;最后用御剑扫描到了index.php.swp 访问一下得到源码 源码如下 <?phpob_start();function get_hash(){$chars ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstu…...

微服务三十五关

1.微服务有什么好处&#xff1f; 微服务优点很多&#xff0c;但是我们通常说一个东西好肯定会跟另一个东西比较&#xff0c; 通常说微服务好会和单体项目进行比较。以下是微服务相对于单体项目的一些显著好处&#xff1a; 首先&#xff0c;让我们讨论单体项目的一些主要缺点&a…...

第一个 Angular 项目 - 添加服务

第一个 Angular 项目 - 添加服务 这里主要用到的内容就是 [Angular 基础] - service 服务 提到的 前置项目在 第一个 Angular 项目 - 动态页面 这里查看 想要实现的功能是简化 shopping-list 和 recipe 之间的跨组件交流 回顾一下项目的结构&#xff1a; ❯ tree src/app/…...

红日靶场3

靶场链接&#xff1a;漏洞详情 在虚拟机的网络编辑器中添加两个仅主机网卡 信息搜集 端口扫描 外网机处于网端192.168.1.0/24中&#xff0c;扫描外网IP端口&#xff0c;开放了80 22 3306端口 80端口http服务&#xff0c;可以尝试登录网页 3306端口mysql服务&#xff0c;可…...

B树的介绍

R-B Tree 简介特性B树特性m阶B树的性质&#xff08;这些性质是B树规定的&#xff09; B树的搜索B树的添加B树的删除——非叶子结点 简介 R-B Tree又称为Red-Black Tree&#xff0c;红黑树。是一种特殊的二叉查找树&#xff0c;红黑树的每个节点上都有存储为表示结点的颜色&…...

《The Art of InnoDB》第二部分|第4章:深入结构-磁盘结构-撕裂的页面(doublewrite buffer)

4.5 撕裂的页面 目录 4.5 撕裂的页面 4.5.1 双写缓冲区的作用 4.5.2 双写缓冲区的结构 4.5.3 双写缓冲区与Redolog的协同工作流程 4.5.2 双写缓冲区写入时机 4.5.3 禁用双写缓冲区 4.5.4 小结 未完待续... 上文我们学习了redo log的结构和其工作原理,它是一个…...

提示工程(Prompt Engineering)、微调(Fine-tuning) 和 嵌入(Embedding)

主要参考资料&#xff1a; 还没搞懂嵌入&#xff08;Embedding&#xff09;、微调&#xff08;Fine-tuning&#xff09;和提示工程&#xff08;Prompt Engineering&#xff09;&#xff1f;: https://blog.csdn.net/DynmicResource/article/details/133638079 B站Up主Nenly同学…...

【Flink精讲】Flink 内存管理

面临的问题 目前&#xff0c; 大数据计算引擎主要用 Java 或是基于 JVM 的编程语言实现的&#xff0c;例如 Apache Hadoop、 Apache Spark、 Apache Drill、 Apache Flink 等。 Java 语言的好处在于程序员不需要太关注底层内存资源的管理&#xff0c;但同样会面临一个问题&…...

正则化概念及使用

正则化概念及使用 正则化概念正则化原理常用的两种正则化方法1. L1 正则化&#xff08;Lasso&#xff09;2. L2 正则化&#xff08;Ridge&#xff09; 正则化参数 正则化概念 在机器学习中&#xff0c;我们致力于通过从训练数据中学习模式或规律来构建模型。为了找到最佳的模型…...

让程序员设计B端界面,好比武大郎招聘:向我看齐。不忍直视!

hello&#xff0c;我是大美B端工场&#xff0c;B端系统的要求越来越高了&#xff0c;很多公司还让程序员负责页面&#xff0c;页面搞的没法看&#xff0c;也怪不得程序员。程序员来搞页面&#xff0c;那还不是武大郎招聘——向我看齐&#xff0c;以我的标准为标准吗&#xff1f…...

使用python构建Android,探索跨平台应用开发Kivy框架

使用python构建Android&#xff0c;探索跨平台应用开发Kivy框架 1. 介绍Kivy框架 Kivy是什么&#xff1f; Kivy是一个开源的Python跨平台应用程序开发框架&#xff0c;旨在帮助开发者快速构建创新的、可扩展的移动应用和多点触控应用。Kivy采用MIT许可证&#xff0c;允许开发…...

08 Redis之集群的搭建和复制原理+哨兵机制+CAP定理+Raft算法

5 Redis 集群 2.8版本之前, Redis采用主从集群模式. 实现了数据备份和读写分离 2.8版本之后, Redis采用Sentinel哨兵集群模式 , 实现了集群的高可用 5.1 主从集群搭建 首先, 基本所有系统 , “读” 的压力都大于 “写” 的压力 Redis 的主从集群是一个“一主多从”的读写分…...

*MYSQL--索引--内部原理

MYSQL的索引根据功能,主要有三大类型: 1.HASH索引 2.二叉树 3.BTREE索引 一:HASH索引 1.内部原理: 在设置了某列为索引列之后,并且开始或者将要在相应索引列创建数据的时候,系统通过某种算法 F(X) 自动计算出来一个十六进制的哈希值,这个哈希值能够对应相应的字段值 所以…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

简单介绍C++中 string与wstring

在C中&#xff0c;string和wstring是两种用于处理不同字符编码的字符串类型&#xff0c;分别基于char和wchar_t字符类型。以下是它们的详细说明和对比&#xff1a; 1. 基础定义 string 类型&#xff1a;std::string 字符类型&#xff1a;char&#xff08;通常为8位&#xff09…...