Python如何实现模板方法设计模式?什么是模板方法设计模式?Python 模板方法设计模式示例代码

什么是模板方法(Template Method)设计模式?

模板方法(Template Method)是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。这种模式允许子类为一个算法的特定步骤提供实现,而不改变算法的结构。

在这里插入图片描述
在这里插入图片描述

模板方法模式通常包含两种类型的方法:

  1. 模板方法(Template Method): 定义了算法的骨架,提供了一个顶级的方法来定义算法的结构,这个方法通常是 final 或者不可被子类重写的。模板方法一般会调用一系列的抽象方法或者具体方法。

  2. 抽象方法(Abstract Method): 在模板方法中被声明但是没有实现,需要子类来实现具体的行为。

主要角色:

  1. 抽象类(Abstract Class): 包含模板方法和抽象方法定义算法的结构和步骤。

  2. 具体子类(Concrete Subclasses): 实现抽象类中的抽象方法,提供特定步骤的具体实现。

工作原理:

  1. 定义算法的骨架,包含一个模板方法。
  2. 模板方法定义了算法的步骤,其中某些步骤是抽象的,由子类实现。
  3. 子类提供特定步骤的实现,但整个算法的流程控制由模板方法负责。

python3 实现模板方法设计模式示例代码(一):

一个简单的示例是咖啡和茶的制备过程。制备咖啡和茶有相似的步骤(比如冲泡和加调味品),但是具体的饮料种类和调味品可能有所不同。在模板方法模式中,可以将冲泡和加调味品等步骤定义为模板方法,而具体的咖啡和茶则是子类,负责实现具体的冲泡方式和调味品。

这种模式允许在不改变算法结构的情况下,定制算法中的特定步骤。

以下是一个使用模板方法设计模式的 Python 示例,模拟了制备咖啡和茶的过程:

from abc import ABC, abstractmethod# 抽象类定义了模板方法
class Beverage(ABC):def prepare(self):self.boil_water()self.brew()self.pour_in_cup()if self.customer_wants_condiments():self.add_condiments()def boil_water(self):print("Boiling water")@abstractmethoddef brew(self):passdef pour_in_cup(self):print("Pouring into cup")@abstractmethoddef add_condiments(self):pass# 钩子方法def customer_wants_condiments(self):return True# 具体子类实现特定的步骤
class Coffee(Beverage):def brew(self):print("Dripping coffee through filter")def add_condiments(self):print("Adding sugar and milk")def customer_wants_condiments(self):response = input("Do you want to add sugar and milk? (y/n): ")return True if response.lower() == 'y' else Falseclass Tea(Beverage):def brew(self):print("Steeping the tea")def add_condiments(self):print("Adding lemon")def customer_wants_condiments(self):response = input("Do you want to add lemon? (y/n): ")return True if response.lower() == 'y' else False# 客户端代码
if __name__ == "__main__":print("Making coffee...")coffee = Coffee()coffee.prepare()print("\nMaking tea...")tea = Tea()tea.prepare()

在这个示例中,Beverage 是抽象类,定义了制备饮料的模板方法 prepare(),以及一些抽象方法(brew()add_condiments())。CoffeeTea 类是具体的子类,分别实现了咖啡和茶的具体制作步骤。通过模板方法 prepare(),它们调用了抽象方法完成了饮料的制作。其中 customer_wants_condiments() 是一个钩子方法,允许子类控制特定步骤的实现。

python3 实现模板方法设计模式示例代码(二):

当考虑更实际的场景时,模板方法模式可以应用在日志记录中。无论是将日志记录到文件、数据库或者控制台,都有相似的流程,但每种记录方式的具体步骤略有不同。

from abc import ABC, abstractmethodclass Logger(ABC):def log(self):self.connect()self.format_log()self.write_log()self.disconnect()@abstractmethoddef connect(self):pass@abstractmethoddef format_log(self):pass@abstractmethoddef write_log(self):pass@abstractmethoddef disconnect(self):passclass FileLogger(Logger):def connect(self):print("File Logger: Connecting to file...")def format_log(self):print("File Logger: Formatting log...")def write_log(self):print("File Logger: Writing log to file...")def disconnect(self):print("File Logger: Disconnecting from file...")class DatabaseLogger(Logger):def connect(self):print("Database Logger: Connecting to database...")def format_log(self):print("Database Logger: Formatting log...")def write_log(self):print("Database Logger: Writing log to database...")def disconnect(self):print("Database Logger: Disconnecting from database...")class ConsoleLogger(Logger):def connect(self):print("Console Logger: Connecting to console...")def format_log(self):print("Console Logger: Formatting log...")def write_log(self):print("Console Logger: Displaying log on console...")def disconnect(self):print("Console Logger: Disconnecting from console...")if __name__ == "__main__":file_logger = FileLogger()file_logger.log()print("\n")db_logger = DatabaseLogger()db_logger.log()print("\n")console_logger = ConsoleLogger()console_logger.log()

这个示例展示了不同类型的日志记录器(文件记录、数据库记录、控制台输出)共享相同的记录流程,但具体的记录方式各不相同。Logger 类定义了模板方法 log(),而各种记录器类实现了该方法的抽象步骤。这样,无论是文件记录、数据库记录还是控制台输出,都能使用相同的模板方法进行记录。


使用模板方法设计模式时,需要注意哪些地方?

在使用模板方法设计模式时,需要注意以下几个方面:

  1. 定义模板方法: 确保模板方法中包含算法的骨架,定义了整个算法的流程和顺序。模板方法应该是 final 或者不可被子类重写,以确保算法的稳定性。

  2. 区分抽象和具体方法: 确保正确地区分抽象方法和具体方法。抽象方法应该由子类来实现,而具体方法可以在抽象类中提供默认实现。

  3. 保持一致性和稳定性: 模板方法模式旨在定义算法的骨架,并且尽可能提供稳定的算法结构。因此,在使用模板方法时,应该确保算法中的步骤是稳定和一致的。

  4. 钩子方法的使用: 如果需要在模板方法中控制特定步骤的实现,可以使用钩子方法(即具有默认实现的方法),允许子类控制或改变算法的部分步骤。

  5. 维护封装性: 确保在子类中不会直接访问或修改父类中的其他方法或属性,以保持对象的封装性。

  6. 避免滥用模板方法模式: 不要为了使用模板方法模式而人为地将一些不相关的操作强行放入模板方法中,这可能会导致类过于臃肿和难以维护。

  7. 适当的抽象级别: 考虑模板方法的抽象级别,要确保足够的抽象来适应各种子类的实现,但不要过度抽象导致子类难以实现。

总的来说,使用模板方法设计模式时,需要注意定义模板方法、合理使用抽象和具体方法、保持一致性和稳定性,以及保持良好的封装性。同时,要根据实际情况和需求适当地使用钩子方法,并避免滥用模板方法模式。


本文就到这里了,感谢您的阅读 。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇

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

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

相关文章

前后端黄金组合:Django+Vue+Element UI,助你构建完美平台!

这是一篇什么文章? 一篇你对测试开发工作感兴趣,想了解系统工作逻辑的文章。 一篇是你在开始动手搭建环境前需要了解各工具原理的文章。 这是一篇你真正开始前需要查阅的文章。 本文介绍了前后端工作原理,前后端搭建的流程、搭建过程中需…

SQLMAP --TAMPER的编写

跟着师傅的文章进行学习 sqlmap之tamper脚本编写_sqlmap tamper编写-CSDN博客 这里学习一下tamper的编写 这里的tamper 其实就是多个绕过waf的插件 通过编写tamper 我们可以学会 在不同过滤下 执行sql注入 我们首先了解一下 tamper的结构 这里我们首先看一个最简单的例子…

Excel数据可视化—波士顿矩阵图【四象限图】

EXCEL系列文章目录 Excel系列文章是本人亲身经历职场之后萌发的想法,为什么Excel覆盖如此之广,几乎每个公司、学校、家庭都在使用,但是它深藏的宝藏功能却很少被人使用,PQ、BI这些功能同样适用于数据分析;并且在一些需…

Kubernetes(k8s)进阶

文章目录 Kubernetes进阶一、Namespace(名称空间)1.namespace介绍2.管理namespace查看namespace创建namespace删除namespaceyaml文件配置namespace 二、Pod(最小基本部署单元)1.pod介绍2.管理pod创建并运行pod查看pod信息访问pod删…

一周互联网简讯 | 本周互联网发生了啥?(第3期)

1.百度T7跳槽字节3-1,总包145万,压力太大想降级 硕士毕业工作10年,一百度T7大头兵发文称,自己最近拿到字节3-1的offer,年包从现有的110万涨30%到145万。但是担心去字节后因为定的职级高需要带人,压力会很大…

【Highway-env】IntersectionEnv代码阅读

文章目录 主要完成任务代码结构1.action space2.default_config3.reward_agent_rewards_agent_reward_reward_rewards小结 4.terminated & truncated5.reset_make_road_make_vehicles_spawn_vehicle 6.step 主要完成任务 IntersectionEnv继承自AbstractEnv,主要完成以下4个…

【django+vue】项目搭建、解决跨域访问

笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~ 【djangovue】项目搭建、解决跨域访问 djangovue介绍vue环境准备vue框架搭建1.创建vue项目2.配置vue项目3.进入项目目录4.运行项目5.项目文件讲解6.vue的扩展库或者插件 django环境准备django框架搭建1.使用conda…

day29_Servlet

今日内容 零、 复习昨日 一、Servlet 零、 复习昨日 一、Servlet 1.1 Servlet介绍 javaweb开发,就是需要服务器接收前端发送的请求,以及请求中的数据,经过处理(jdbc操作),然后向浏览器做出响应. 我们要想在服务器中写java代码来接收请求,做出响应,我们的java代码就得遵循tomca…

k8s ingress高级用法一

前面的文章中,我们讲述了ingress的基础应用,接下来继续讲解ingress的一些高级用法 一、ingress限流 在实际的生产环境中,有时间我们需要对服务进行限流,避免单位时间内访问次数过多,常用的一些限流的参数如下&#x…

工作电压范围,转换速率高,相位补偿等特性的双运算放大器芯片D4510的描述

D4510是一块双运算放大器,具有较宽的工作电压范围,转换速率高,相位补偿等特性。电路能在低电源电压下:工作,电源电压范围:双电源为1V-3.5V和单电源电压为2V~7V。 主要特点: ● 低电压工作 ● 转换速率高 ● 动态输…

docker中怎么启动容器

1、首先在linux中使用以下命令来启动 Docker 服务: sudo systemctl start docker2、然后下面的命令显示所有的容器列表,包括正在运行和已停止的容器。 docker ps -a然后找到容器ID 3、使用 docker start 启动一个已停止的容器: docker s…

简单模拟 Spring 创建的动态代理类(解释一种@Transactional事务失效的场景)

模拟 Spring 创建的动态代理类 本文主要目的是从父类和子类继承的角度去分析为什么在 Service 标注的业务类中使用 this 调用方法会造成事务失效。解释在这种情况下 this 为什么是原始类对象而不是代理类对象。 问题描述 在 Service 标注的业务类中,如果调用本类…

YOLOv8 加持 MobileNetv3,目标检测新篇章

🗝️YOLOv8实战宝典--星级指南:从入门到精通,您不可错过的技巧   -- 聚焦于YOLO的 最新版本, 对颈部网络改进、添加局部注意力、增加检测头部,实测涨点 💡 深入浅出YOLOv8:我的专业笔记与技术总结   -- YOLOv8轻松上手, 适用技术小白,文章代码齐全,仅需 …

【狂神说Java】redis入门

✅作者简介:CSDN内容合伙人、信息安全专业在校大学生🏆 🔥系列专栏 :【狂神说Java】 📃新人博主 :欢迎点赞收藏关注,会回访! 💬舞台再大,你不上台&#xff0c…

卷?中学生开始学习人工智能和大模型,附课件!

卷?中学生开始学习人工智能和大模型,附课件! 大家好,我是老章 发现一个面向11-14岁人群的AI课程,还附加了大模型内容,浏览了一遍它们的课件(还有面向教师的资源),感觉非…

Linux——编译器gcc/g++、调试器gdb以及自动化构建工具makefilemake详解

编译器—gcc/g、调试器—gdb以及自动化构建工具—makefile&&make 文章目录 编译器—gcc/g、调试器—gdb以及自动化构建工具—makefile&&make1. 编译器——gcc/g1.1 生成可执行文件与修改默认可执行文件1.2 程序的翻译过程以及对应的gcc选项1.2.1 预处理 gcc -E…

【cpolar】TortoiseSVN如何安装并实现公网提交文件到本地SVN服务器

🎥 个人主页:深鱼~ 🔥收录专栏:cpolar 🌄欢迎 👍点赞✍评论⭐收藏 文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控…

RabbitMQ 部署及配置详解(集群部署)

单机部署请移步: RabbitMQ 部署及配置详解 (单机) RabbitMQ 集群是一个或 多个节点,每个节点共享用户、虚拟主机、 队列、交换、绑定、运行时参数和其他分布式状态。 一、RabbitMQ 集群可以通过多种方式形成: 通过在配置文件中列出群集节点以…

JVM的运行时数据区

Java虚拟机(JVM)的运行时数据区是程序在运行过程中使用的内存区域,主要包括以下几个部分: 程序计数器虚拟机栈本地方法栈堆方法区运行时常量池直接内存 不同的虚拟机实现可能会略有差异。这些区域协同工作,支持Java…

(七)什么是Vite——vite优劣势、命令

vite分享ppt,感兴趣的可以下载: ​​​​​​​Vite分享、原理介绍ppt 什么是vite系列目录: (一)什么是Vite——vite介绍与使用-CSDN博客 (二)什么是Vite——Vite 和 Webpack 区别&#xff0…