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

文章目录

  • 一:模板方法设计模式概述
    • 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 {@Overrideprotected void doSomething() {System.out.println("Warrior is fighting!");}
}// 具体类:法师角色
public class MageCharacter extends Character {@Overrideprotected 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.hqwc.cn/news/99554.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css之层叠上下文

之前调元素的显示优先级时,只会默默的调z-index以达到效果,但有时不生效,又不知道根因。刚好详细了解到层叠上下文,可以解释此类问题。 什么是层叠上下文? 在CSS2.1规范中,每个盒模型的位置是三维的&…

macOS通过钥匙串访问找回WiFi密码的详细教程

如果您忘记了Mac电脑上的WiFi密码,可以通过钥匙串访问来找回它。具体步骤如下: 1.打开Mac电脑的“启动台”,然后在其他文件中找到“钥匙串访问”。 2.运行“钥匙串访问”应用程序,点击左侧的“系统”,然后在右侧找到…

中级深入--day19

鼠标动作链 有些时候,我们需要再页面上模拟一些鼠标操作,比如双击、右击、拖拽甚至按住不动等,我们可以通过导入 ActionChains 类来做到: 示例: #导入 ActionChains 类 from selenium.webdriver import ActionChains…

虚拟机(三)VMware Workstation 桥接模式下无法上网

目录 一、背景二、解决方式方式一:关闭防火墙方式二:查看桥接模式下的物理网卡是否对应正确方式三:查看物理主机的网络属性 一、背景 今天在使用 VMware Workstation 里面安装的 Windows 虚拟机的时候,发现虽然在 NAT 模式下可以…

【Sentinel】核心API-Entry与Context

文章目录 一、Entry1、Entry的声明2、使用API自定义资源3、基于SentinelResource注解标记资源 二、Context1、Context介绍2、Context的初始化3、AbstractSentinelInterceptor4、ContextUtil 一、Entry 1、Entry的声明 默认情况下,Sentinel会将controller中的方法作…

Flink实时计算中台Kubernates功能改造点

背景 平台为数据开发人员提供基本的实时作业的管理功能,其中包括jar、sql等作业的在线开发;因此中台需要提供一个统一的SDK支持平台能够实现flink jar作业的发布;绝大多数情况下企业可能会考虑Flink On Yarn的这个发布模式,但是伴随云原生的呼声越来越大,一些企业不希望部…

Java之文件操作与IO

目录 一.认识文件 1.1文件是什么? 1.2文件的组织 1.3文件路径 1.4文件的分类 二.文件操作 2.1File概述 三.文件内容操作--IO 3.1JavaIO的认识 3.2Reader和Writer ⭐Reader类 ⭐Writer类 3.2FileInputStream和FileOutputStream ⭐FileInputStream类 …

Pycharm中出现ImportError:DLL load failed:找不到指定模块的解决方法

不论搭建什么工程,运行什么文件,只要在Pycharm中出现ImportError: DLL load failed: 找不到指定的模块这样的问题,以下方法都适用!!! 一、问题描述 我在使用pycharm连接webots,用python控制机…

设计模式-装饰模式

文章目录 一、简介二、基本概念三、装饰模式的结构和实现类图解析:装饰器的实现方式继承实现:组合实现:继承和组合对比 四、装饰模式的应用场景五、与其他模式的关系六、总结 一、简介 装饰模式是一种结构型设计模式,它允许动态地…

【Unity-Cinemachine相机】相机跟随之Transposer属性

相机跟随和瞄准行为 Transposer:虚拟相机将在某个固定的偏移或距离上跟随目标移动 上面的偏移量就是Follow Offset Binding Mode决定Follow Offset是目标本地坐标系下的身后十米还是世界坐标系下的身后十米 Lock To Target On Assign:锁定自己和目标本地…

【Git-Exception】Git报错:fatal: unable to auto-detect email address

报错信息: *** Please tell me who you are. Run git config --global user.email “youexample.com” git config –global user.name “Your Name” to set your account’s default identity. Omit --global to set the identity only in this repository. fatal…

Unity汉化一个插件 制作插件汉化工具

我是编程一个菜鸟,英语又不好,有的插件非常牛!我想学一学,页面全是英文,完全不知所措,我该怎么办啊...尝试在Unity中汉化一个插件 效果: 思路: 如何在Unity中把一个自己喜欢的插件…