设计模式行为型-模板模式

news2024/12/24 8:13:48

文章目录

  • 一:模板方法设计模式概述
    • 1.1 简介
    • 1.2 定义和目的
    • 1.3 关键特点
    • 1.4 适用场景
  • 二:模板方法设计模式基本原理
    • 2.1 抽象类
      • 2.1.1 定义和作用
      • 2.1.2 模板方法
      • 2.1.3 具体方法
    • 2.2 具体类
      • 2.2.1 定义和作用
      • 2.2.2 实现抽象类中的抽象方法
      • 2.2.3 覆盖钩子方法
  • 三:模板方法设计模式实现步骤
    • 3.1 创建抽象类
      • 3.1.1 声明模板方法
      • 3.1.2 定义具体方法
      • 3.1.3 定义钩子方法
    • 3.2 创建具体类
      • 3.2.1 实现抽象类中的抽象方法
      • 3.2.2 覆盖钩子方法
  • 四:模板方法设计模式应用场景
    • 4.1 实际案例背景介绍
    • 4.2 设计模式解决方案
    • 4.3 实现代码示例
  • 五:模板方法设计模式应用注意事项
    • 5.1 钩子方法的使用场景和注意事项
    • 5.2 与其他设计模式的关系
    • 5.3 使用建议和最佳实践
  • 结语

一:模板方法设计模式概述

1.1 简介

模板方法设计模式是一种行为型设计模式,它定义了一个算法的骨架,在其中某些步骤由具体子类来实现。

1.2 定义和目的

模板方法设计模式通过将算法通用部分放在抽象类中,具体实现留给具体子类来完成,以提高代码的复用性和可维护性。
在这里插入图片描述

1.3 关键特点

  • 模板方法:定义算法的骨架,其中某些步骤由具体子类来实现。
  • 具体方法:抽象类中已经实现的方法,子类不能修改。
  • 钩子方法:抽象类中定义的可选方法,具体子类选择性地覆盖,可以改变模板方法的行为。

1.4 适用场景

  • 当算法有固定的结构或步骤,并且步骤之间存在关联性时,可以使用模板方法设计模式。
  • 当需要在不同上下文中应用相似的算法时,可以使用模板方法设计模式。
  • 当希望通过基类来控制子类的行为时,可以使用模板方法设计模式。

二:模板方法设计模式基本原理

2.1 抽象类

2.1.1 定义和作用

抽象类是模板方法设计模式的核心角色,它定义了模板方法和一系列抽象方法,描述算法的结构和步骤。

2.1.2 模板方法

模板方法是抽象类中定义的方法,描述算法的骨架。该方法通常是final类型的,以防止子类对其进行修改。

2.1.3 具体方法

具体方法是抽象类中已经实现的方法,子类不能修改。这些方法通常是模板方法所需要的辅助方法或公共方法。

2.2 具体类

2.2.1 定义和作用

具体类是抽象类的子类,负责实现抽象类中的抽象方法,完成算法的具体实现。

2.2.2 实现抽象类中的抽象方法

具体类需要实现抽象类中定义的抽象方法,完成算法的具体实现。

2.2.3 覆盖钩子方法

具体类可以选择性地覆盖抽象类中定义的钩子方法,以改变模板方法的行为。

三:模板方法设计模式实现步骤

3.1 创建抽象类

3.1.1 声明模板方法

在抽象类中声明模板方法,描述算法的骨架。通常将该方法设置为final类型,防止子类修改。

3.1.2 定义具体方法

在抽象类中定义具体方法,这些方法在模板方法中被调用。这些方法通常是私有或受保护的,不允许子类直接调用。

3.1.3 定义钩子方法

定义可选的钩子方法,根据需要提供默认实现或为空实现。具体子类可以选择性地覆盖这些方法以改变模板方法的行为。

3.2 创建具体类

3.2.1 实现抽象类中的抽象方法

创建具体类并实现抽象类中的抽象方法,完成算法的具体实现。

3.2.2 覆盖钩子方法

具体类可以选择性地覆盖抽象类中的钩子方法,以改变模板方法的行为。

四:模板方法设计模式应用场景

4.1 实际案例背景介绍

假设我们正在开发一个游戏,这个游戏中有多个角色,每个角色都有不同的行为和技能。我们需要设计一个通用的角色创建流程,以确保每个角色的创建过程都符合一定的规范和约束。这就是一个适用于模板方法设计模式的实际案例。

4.2 设计模式解决方案

我们可以使用模板方法设计模式来解决上述问题。首先,我们创建一个抽象类作为角色的基类,其中包含了一个模板方法用于控制角色的创建流程。具体的角色类继承这个抽象类,并实现其中的抽象方法来完成自己特定的行为和技能。

在抽象类中,我们可以定义一些公共的方法,比如角色的初始化方法、资源加载方法等,这些方法已经实现并且不允许子类修改。同时,我们也可以定义一些钩子方法,用于在角色创建的不同阶段插入一些额外的逻辑。

抽象类中的模板方法定义了角色的创建流程,它按照一定的顺序调用了一系列的具体方法和钩子方法。这些具体方法和钩子方法由具体的角色类来实现,根据不同的需求来完成具体的行为和技能。

通过使用模板方法设计模式,我们可以将公共的部分提取到抽象类中,实现了代码的复用和可维护性的提高。同时,具体的角色类也能够灵活地实现自己特定的行为和技能,满足了游戏中多样化的角色需求。

4.3 实现代码示例

下面是一个简单的实现代码示例,演示了如何使用模板方法设计模式来创建游戏角色:

// 抽象类:角色
public abstract class Character {
    // 模板方法:创建角色
    public final void createCharacter() {
        initialize();   // 初始化角色
        loadResources();    // 加载资源
        doSomething();  // 具体行为
        hookMethod();   // 钩子方法
    }
    
    // 具体方法:初始化角色
    private void initialize() {
        System.out.println("Initializing character...");
    }
    
    // 具体方法:加载资源
    private void loadResources() {
        System.out.println("Loading resources...");
    }
    
    // 抽象方法:具体行为
    protected abstract void doSomething();
    
    // 钩子方法:可选的逻辑
    protected void hookMethod() {
        // 默认为空实现,子类可选择性地覆盖
    }
}

// 具体类:战士角色
public class WarriorCharacter extends Character {
    @Override
    protected void doSomething() {
        System.out.println("Warrior is fighting!");
    }
}

// 具体类:法师角色
public class MageCharacter extends Character {
    @Override
    protected void doSomething() {
        System.out.println("Mage is casting spells!");
    }
}

// 测试代码
public class Main {
    public static void main(String[] args) {
        Character warrior = new WarriorCharacter();
        warrior.createCharacter();   // 输出:Initializing character... Loading resources... Warrior is fighting!
        
        Character mage = new MageCharacter();
        mage.createCharacter();  // 输出:Initializing character... Loading resources... Mage is casting spells!
    }
}

在上面的示例中,Character 是抽象类,其中的 createCharacter() 方法是模板方法,控制了角色的创建流程。具体的角色类 WarriorCharacterMageCharacter 继承了 Character 并实现了其中的抽象方法 doSomething(),完成了自己特定的行为。最后,在 Main 类中测试了这两个具体的角色类的创建过程。

通过运行上述代码示例,你可以看到不同角色的创建流程遵循了模板方法定义的骨架,但同时具体的角色类可以根据自身的需求实现不同的行为和技能。这就是模板方法设计模式的应用。

五:模板方法设计模式应用注意事项

5.1 钩子方法的使用场景和注意事项

钩子方法是在模板方法设计模式中的一种特殊方法,它在抽象类中提供了一个默认的空实现,子类可以选择性地覆盖或扩展这个方法。钩子方法的主要作用是允许子类在模板方法的特定点插入自己的逻辑,以实现对算法的定制和扩展。

使用钩子方法可以使得模板方法更加灵活和可扩展,同时也可以避免在抽象类中定义过多的抽象方法,简化了子类的实现。

一般来说,钩子方法的使用场景包括但不限于以下几种情况:

  1. 选择性执行:某些步骤在特定条件下需要执行,而在其他条件下可以跳过,钩子方法可以判断这些条件并决定是否执行相应步骤。
  2. 扩展功能:在模板方法的特定点添加新的逻辑或功能,用于满足不同的需求。
  3. 改变顺序:通过覆盖或扩展钩子方法,改变模板方法中步骤的执行顺序。

在使用钩子方法时,需要注意以下几点:

  1. 钩子方法的命名:钩子方法应该具有描述性的、能够体现其作用的命名,以便子类理解和正确使用。
  2. 钩子方法的默认实现:钩子方法在抽象类中应该有一个默认的空实现,以保证子类可以选择是否覆盖它。
  3. 钩子方法的调用时机:钩子方法应该在适当的时机被调用,以确保它们的逻辑能够正确地插入到模板方法中。

5.2 与其他设计模式的关系

模板方法设计模式与其他设计模式之间存在一些关系和区别。下面是一些常见的与模板方法设计模式相关的设计模式:

  1. 工厂方法模式(Factory Method Pattern):工厂方法模式也是一种创建型设计模式,它将对象的创建延迟到子类中进行。在工厂方法模式中,模板方法用于定义对象的创建过程,具体的产品由子类来实现。可以说,工厂方法模式是模板方法设计模式在创建对象方面的一种应用。
  2. 策略模式(Strategy Pattern):策略模式用于封装一系列的算法,并使它们可以互相替换。在策略模式中,每个算法都是一个独立的类,而模板方法则是在抽象类中定义的一系列步骤。可以说,策略模式是模板方法设计模式在算法封装方面的一种应用。

需要注意的是,模板方法设计模式和以上提到的设计模式并不是相互排斥的关系,它们可以结合使用来解决复杂的问题。在实际开发中,根据具体的需求和场景选择合适的设计模式,能够更好地设计和实现高质量的代码。

5.3 使用建议和最佳实践

以下是一些使用模板方法设计模式的建议和最佳实践:

  1. 合理划分抽象类和具体类:抽象类应该包含公共的行为和模板方法,具体类应该实现自己特定的行为。
  2. 提取公共的方法和逻辑:将公共的方法和逻辑提取到抽象类中,以避免代码的重复和冗余。
  3. 明确模板方法的执行流程:定义好模板方法的执行顺序,并确保每个步骤的执行时机正确。
  4. 合理使用钩子方法:在需要灵活定制或扩展的地方使用钩子方法,但不要滥用。过多的钩子方法可能导致代码难以理解和维护。
  5. 考虑模板方法的可变性:模板方法应该具有一定的可变性,以便子类可以根据自身需要进行定制。但同时也要保持模板方法的稳定性和一致性。

结语

模板方法设计模式是一种行为设计模式,它通过定义一个算法的骨架,在抽象类中封装了算法的主要步骤,并使用抽象方法和钩子方法来实现可变的部分。这种设计模式使得算法的结构保持稳定,而具体的实现细节可以由子类提供。

模板方法设计模式的优势在于:

  1. 提高代码复用性:将共同的代码逻辑封装在抽象类中,可以在不同的子类中共享使用,避免了重复编写相似的代码。
  2. 简化子类实现:通过将算法中的可变部分定义为抽象方法,子类只需要关注自己特定的实现细节,从而简化了子类的实现。
  3. 提供扩展点:通过钩子方法,允许子类在特定的执行点插入自己的逻辑,以实现对算法的定制和扩展。

然而,在使用模板方法设计模式时也需要考虑一些因素和注意事项:

  1. 需要明确模板方法的执行流程和步骤顺序,确保每个步骤的执行时机正确。
  2. 钩子方法应该有默认的空实现,以保证子类可以选择是否覆盖它。
  3. 合理使用钩子方法,不要过度使用,避免引入不必要的复杂性。
  4. 钩子方法的命名应该具有描述性,以便子类理解和正确使用。

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

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

相关文章

学生信息管理系统MIS(前端)

改造HTML文件 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>学生信息管理系统MIS</title><!-- link在HTML文件中,引入外部的css文件 rel的值是固定写法,stylesheet样式表href用来指定样式表的位置--><lin…

CleanMyMac X2024软件最新版本更新下载

CleanMyMac X是一款颇受欢迎的专业清理软件&#xff0c;拥有十多项强大的功能&#xff0c;可以进行系统清理、清空废纸篓、清除大旧型文件、程序卸载、除恶意软件、系统维护等等&#xff0c;并且这款清理软件操作简易&#xff0c;非常好上手&#xff0c;特别适用于那些刚入手苹…

企业架构LNMP学习笔记5

Nginx&#xff1a; 常见用法&#xff1a; 1&#xff09;web服务器软件 httpd http协议 同类的web服务器软件&#xff1a;apache Nginx&#xff08;俄罗斯&#xff09;IIS&#xff08;微软&#xff09;lighttpd&#xff08;德国&#xff09; 2&#xff09;代理服务器 反向代…

springboot:时间格式化的5种方法(解决后端传给前端的时间格式转换问题)推荐使用第4和第5种!

本文转载自&#xff1a;springboot&#xff1a;时间格式化的5种方法&#xff08;解决后端传给前端的时间显示不一致&#xff09;_为什么前端格式化日期了后端还要格式化_洛泞的博客-CSDN博客 时间问题演示 为了方便演示&#xff0c;我写了一个简单 Spring Boot 项目&#xff…

设计模式-工厂模式Factory

工厂模式 b.工厂方法模式 (Factory Method) (重点)1) 简单工厂 Simple Factory1.a) 简单工厂的好处 2) 工厂方法 Factory Method2.a) 对工厂进行抽象化 (版本一)2.b) 对工厂进行缓存 (版本二)2.c) 加载配置文件到缓存中 (版本三)c.1) 产品线 c.抽象工厂模式 (Abstract Factory)…

五子棋游戏禁手算法的改进

五子棋游戏禁手算法的改进 五子棋最新的禁手规则&#xff1a; 1&#xff0e;黑棋禁手判负、白棋无禁手。黑棋禁手有“三三”&#xff08;包括“四三三”&#xff09;、“四四”&#xff08;包括“四四三”&#xff09;和“长连”。黑棋只能以“四三”取胜。 2&#xff0e;黑方…

B端系统设计之【权限】详解

衡量B端产品系统好坏的一个重要标准就是它的权限是否细致&#xff0c;拓展性是否强。 权限管理是B端产品系统的基础&#xff0c;好的权限管理系统延展性较强&#xff0c;即使业务发生变化也能避免大改和推倒重建。 权限分类 1、功能权限 功能权限是指用户登录系统之后&#xff…

前端面试中Vue的有经典面试题三

11. 网页从输入网址到渲染完成经历了哪些过程&#xff1f; 大致可以分为如下7步&#xff1a; 输入网址&#xff1b; 发送到DNS服务器&#xff0c;并获取域名对应的web服务器对应的ip地址&#xff1b; 与web服务器建立TCP连接&#xff1b; 浏览器向web服务器发送http请求&a…

【自用】西门子s7-200连接显示屏和物联网盒子完整配置过程

总览 1.PLC配置 2.显示屏配置 3.物联网盒子配置 一、PLC配置 1.连接PLC软件 STEP-7MicroWIN V4.0 SP9完整版 链接&#xff1a;https://pan.baidu.com/s/17LMEXnbkQZMPI8Bte24Eug?pwdjsi3 提取码&#xff1a;jsi3 2.PLC配置 打开 PLC 上面的小盖子&#xff0c;把红色按钮…

【代码随想录day23】不同路径 II

题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上角到…

3.1.6 练习 基于GPA排名计算本专业保研名单

C自学精简教程 目录(必读) GPA概念回顾 平均学分绩点GPA(Grade Point Average)是对一个学生大学学习成绩的综合的衡量指标。 在前面的文章 本科生学分绩点GPA计算 中&#xff0c;我们知道了什么是平均学分绩点GPA&#xff0c;以及如何计算它。 基于GPA给学生排名 现在我们…

介绍几种使用工具

FileWatch&#xff0c;观测文件变化&#xff0c;源码地址&#xff1a;https://github.com/ThomasMonkman/filewatch nlohmann::json&#xff0c;json封装解析&#xff0c;源码地址&#xff1a;https://github.com/nlohmann/json optionparser&#xff0c;解析选项&#xff0c;源…

4.(Python数模)0-1规划

Python解决0-1规划问题 参考下面文章 源代码 import pulp # 导入 pulp 库# 主程序 def main():# 投资决策问题&#xff1a;# 公司现有 5个拟投资项目&#xff0c;根据投资额、投资收益和限制条件&#xff0c;问如何决策使收益最大。"""问题建模&#x…

9. 微积分 - 导数

文章目录 导数求导实例代码演示:迭代法求解二次函数最小值阶Hi, 大家好。我是茶桁。 我们终于结束了极限和连续的折磨,开启了新的篇章。 不过不要以为我们后面的就会很容易,只是相对来说, 没有那么绕而已。 那么,我们今天开始学习「导数」。 导数 在之前的导论,也就是…

【算法竞赛宝典】求分数精确值

【算法竞赛宝典】求分数精确值 题目描述思路讲解代码展示 题目描述 思路讲解 代码展示 //计算分数的精确值 #include<iostream>using namespace std; int remainder[101], quotient[101]; //remainder:存放除法的余数;quotient:依次存放商的每一位int main() {int m, n,…

[CISCN 2019初赛]Love Math

文章目录 前言考点解题过程 前言 感慨自己实力不够&#xff0c;心浮气躁根本做不来难题。难得这题对我还很有吸引力&#xff0c;也涉及很多知识。只能说我是受益匪浅&#xff0c;总的来说加油吧ctfer。 考点 利用php动态函数的特性利用php中的数学函数实现命令执行利用php7的特…

项目验收有哪些流程?

验收流程 科技计划项目验收/课题验收测试服务的被测对象是国家重大专项、科研课题的软件成果物&#xff0c;可以是一个模块、软件或系统等&#xff0c;也可以是软件套件或软件原型等。测试范围主要来源于课题的合同书/可行吧报告/申报书中的技术指标要求。所出具的科技项目验收…

中东 Shopify 如何使用 Bytebase 构建一站式数据库开发工作流

公司简介 Salla 是一家 2016 年成立&#xff0c;位于沙特麦加的自建站电商平台。 作为中东 Shopify&#xff0c;其最大的特点是支持阿拉伯语建站&#xff0c;并且提供更多适应中东地区特点的本地化服务。截止目前&#xff0c;已有 47,000 家店铺入驻 Salla&#xff0c;商品销售…

并发测试工具 apache-jmeter使用发送post请求JSON数据

目录 1 下载安装 2 汉化 3 创建高并发测试 配置线程组 创建web请求 创建监听器 结果树 汇总报告 为web请求添加token 添加Content-Type用于发送json 4 启动测试 5 查看结果 1 下载安装 官网Apache JMeter - Download Apache JMeter 解压运行 2 2 汉化 打开软件…

CS144环境配置问题

使用wsl来做CS144实验&#xff0c;可能会在编译的时候遇到以下问题&#xff0c;很明显是找不到LIBPCAP&#xff0c;参考链接 使用sudo apt-get install libpcap-dev命令下载该库即可。 CMake Error: The following variables are used in this project, but they are set to N…