【设计模式】 模板方法模式

前言

1. 单例模式(Singleton Pattern):保证一个类只有一个实例,并提供一个全局的访问点。

2. 工厂模式(Factory Pattern):定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。

3. 观察者模式(Observer Pattern):定义对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会被自动通知并更新。

4. 装饰器模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,而不会影响到其他对象。

5. 策略模式(Strategy Pattern):定义一系列的算法,将每个算法封装起来,并使它们可以相互替换。

6. 命令模式(Command Pattern):将请求封装成一个对象,从而使用户可以用不同的请求对客户进行参数化。

7. 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的类能够一起工作。

8. 外观模式(Facade Pattern):为子系统中的一组接口提供一个统一的接口,从而使得子系统更加容易使用。

9. 状态模式(State Pattern):允许一个对象在其内部状态改变时改变其行为。

10. 模板方法模式(Template Method Pattern):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中实现。

这些是Python中常用的设计模式,通过使用这些设计模式可以提高代码的可读性、可维护性和重用性。

模板方法模式

模板方法模式是一种行为设计模式,它定义一个算法的骨架,而将一些步骤延迟到子类中。这种模式使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

组成成分

  • 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下。
    • 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
    • 基本方法:是整个算法中的一个步骤,包含以下几种类型。
      • 抽象方法:在抽象类中申明,由具体子类实现。
      • 具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。
  • 具体子类(Concrete Class):实现抽象类中所定义的抽象方法,它们是一个顶级逻辑的一个组成步骤。

具体实例一

制作饮料的模板

from abc import ABC, abstractmethod# 模板方法模式的抽象类
class BeverageTemplate(ABC):# 模板方法定义了算法的骨架def prepare_beverage(self):self.boil_water()self.brew()self.pour_in_cup()self.add_condiments()# 具体步骤由子类实现@abstractmethoddef brew(self):pass@abstractmethoddef add_condiments(self):pass# 公共步骤def boil_water(self):print("Boiling water")def pour_in_cup(self):print("Pouring into cup")# 具体子类实现
class Coffee(BeverageTemplate):def brew(self):print("Brewing coffee grounds")def add_condiments(self):print("Adding sugar and milk")class Tea(BeverageTemplate):def brew(self):print("Steeping the tea")def add_condiments(self):print("Adding lemon")# 客户端代码
if __name__ == "__main__":print("Making Coffee:")coffee = Coffee()coffee.prepare_beverage()print("\nMaking Tea:")tea = Tea()tea.prepare_beverage()

 BeverageTemplate是抽象类,定义了制作饮料的模板方法 prepare_beverage 和一些具体的步骤,如煮水和倒入杯中。CoffeeTea 是具体的子类,分别实现了 brewadd_condiments 方法,定义了各自的饮料制作步骤。

 具体实例二

 出国留学手续设计程序

 流程:索取学校资料提出入学申请办理因私出国护照出境卡和公证申请签证体检订机票准备行装抵达目标学校

  • 通用流程实现在父类

  1. 办理因私出国护照、出境卡和公证
  2. 申请签证
  3. 体检、订机票、准备行装
class StudyAbroad():def procedure(self):self.LookingForSchool() # 索取学校资料self.ApplyForEnrol()  # 入学申请self.ApplyForPassport()  # 办理因私出国护照、出境卡和公证self.ApplyForVisa()  # 申请签证self.ReadyGoAbroad()  # 体检、订机票、准备行装self.Arriving()  # 抵达
​def LookingForSchool(self):'''索取学校资料'''raise ValueError('LookingForSchool方法未实现')
​def ApplyForEnrol(self):'''入学申请'''raise ValueError('ApplyForEnrol方法未实现')
​def ApplyForPassport(self):'''办理因私出国护照、出境卡和公证'''print('三.办理因私出国护照、出境卡和公证:')print('  1)持录取通知书、本人户口簿或身份证向户口所在地公安机关申请办理因私出国护照和出境卡。')print('  2)办理出生公证书,学历、学位和成绩公证,经历证书,亲属关系公证,经济担保公证。')
​def ApplyForVisa(self):'''申请签证'''print('四.申请签证:')print('  1)准备申请国外境签证所需的各种资料,包括个人学历、成绩单、工作经历的证明;个人及家庭收入、资金和财产证明;家庭成员的关系证明等;')print('  2)向拟留学国家驻华使(领)馆申请入境签证。申请时需按要求填写有关表格,递交必需的证明材料,缴纳签证。有的国家(比如美国、英国、加拿大等)在申请签证时会要求申请人前往使(领)馆进行面试。')
​def ReadyGoAbroad(self):'''体检、订机票、准备行装'''print('五.体检、订机票、准备行装:')print('  1)进行身体检查、免疫检查和接种传染病疫苗;')print('  2)确定机票时间、航班和转机地点。')
​def Arriving(self):'''抵达'''raise ValueError('Arriving方法未实现')
  • 不通用流程是现在具体的子类 
  1. 索取学校资料
  2. 入学申请
  3. 抵达
class StudyInAmerica(StudyAbroad):def LookingForSchool(self):'''索取学校资料'''print('一.索取学校以下资料:')print('  1)对留学意向国家的政治、经济、文化背景和教育体制、学术水平进行较为全面的了解;')print('  2)全面了解和掌握国外学校的情况,包括历史、学费、学制、专业、师资配备、教学设施、学术地位、学生人数等;')print('  3)了解该学校的住宿、交通、医疗保险情况如何;')
​def ApplyForEnrol(self):'''入学申请'''print('二.入学申请:')print('  1)填写报名表;')print('  2)将报名表、个人学历证明、最近的学习成绩单、推荐信、个人简历、托福或雅思语言考试成绩单等资料寄往所申请的学校;')
​def Arriving(self):'''抵达'''print('六.抵达目标学校:')print('  1)安排住宿;')print('  2)了解校园及周边环境。')

调用方法

if __name__ == '__main__':xiaoming = StudyInAmerica()xiaoming.procedure()

优点

  1. 它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
  2. 它在父类中提取了公共的部分代码,便于代码复用。
  3. 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。

缺点

  1. 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
  2. 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。

 

容易混淆的概念

模板设计模式和继承的区别

模板设计模式和继承是两种不同的面向对象编程范式。

模板设计模式是一种行为型设计模式,它定义了一个操作的步骤,允许子类为一个或多个步骤提供不同的实现。这种模式允许在不改变操作的结构的情况下重定义某些步骤的实现

而继承则是一种结构性设计模式,它允许将父类的方法、属性等“继承”到子类中,使得子类可以共享父类的方法和属性。这种模式可以用来构建一系列相关的类,并在不改变每个类的行为的情况下扩展他们的功能。

总之,模板设计模式和继承的区别在于前者更强调子类可以在父类的基础上重新定义部分行为,而后者则更强调子类继承父类的行为

用通俗的话来讲,模板方法模式,在父类中已经定义好了一个流程,流程有很多步骤组成,这个步骤是固定的,不能更改,但有些步骤对所有情况都适用,所以抽出来放在父类中实现;而具体情况具体对待的步骤则要通过不同的子类来各自实现。

应用场景

  1. 框架搭建: 在软件框架中,模板方法模式经常被用于定义框架的基本骨架,而留下一些具体实现的细节给子类。这样,框架的使用者可以通过继承和实现具体步骤来扩展和定制框架的行为。

  2. 库和框架中的回调: 在回调机制中,模板方法模式也很有用。例如,GUI库中的事件处理,库提供一个通用的事件处理框架,而用户通过实现特定的事件处理方法来定义自己的行为。

  3. 算法实现: 当一系列算法有着相似的步骤,但具体实现有所不同时,模板方法模式非常有用。例如,排序算法中,排序的框架可以在父类中定义,而具体的比较和交换步骤则由子类实现。

  4. 生命周期管理: 在对象的生命周期管理中,模板方法模式可以用于定义对象的创建、销毁等步骤,而将具体的实现交给子类。

  5. 流程控制: 在业务流程中,如果有一系列的步骤需要按照一定的顺序执行,但某些步骤的实现可能因情况而异,模板方法模式也是一个合适的选择。

参考链接

《大话设计模式》——模板方法模式(Python版) - 知乎

模板设计模式和继承有啥区别-掘金

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

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

相关文章

2_工厂设计_工厂方法和抽象工厂

工厂设计模式-工厂方法 1.概念 工厂方法模式(Fatory Method Pattern ) 是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。 在工厂方法模式中用户只需要关心所需产品对应的工厂,…

css——box-shadow阴影效果

/* box-shadow:内外阴影(inset:内阴影,水平阴影,垂直阴影,阴影模糊距离,阴影大小,阴影颜色) */box-shadow: 0 0 50px #ccc; 引用来源:box-shadow详解_box-shadow属性详解-CSDN博客

AUTOSAR开发文档

目录 目录 状态机电源管理开发... I 文档... I 1. 综述... 1 2. 系统硬件架构图... 1 3. 状态机设计方案... 2 4. 电源管理方案... 4 综述 本文档主要描述了MCU芯片TC297的AUTOSAR方案。MCU的基础软件由AUTOSAR软件实现&#xff0…

嵌入式——循环队列

循环队列 (Circular Queue) 是一种数据结构(或称环形队列、圆形队列)。它类似于普通队列,但是在循环队列中,当队列尾部到达数组的末尾时,它会从数组的开头重新开始。这种数据结构通常用于需要固定大小的队列,例如计算机内存中的缓冲区。循环队列可以通过数组或链表实现,…

微信小程序实战-01翻页时钟-1

文章目录 前言需求分析功能设计界面设计界面结构设计界面样式设计 逻辑设计 单页功能实现运行结果 前言 我经常在手机上用的一款app有一个功能是翻页时钟,基于之前学习的小程序相关的基础内容,我打算在微信小程序中也设计一个翻页时钟功能,J…

大模型实战营Day2 作业

基础作业 1 使用 InternLM-Chat-7B 模型生成 300 字的小故事 2 熟悉 hugging face 下载功能,使用 huggingface_hub python 包,下载 InternLM-20B 的 config.json 文件到本地 进阶作业 1 完成浦语灵笔的图文理解及创作部署 2 完成 Lagent 工具调用 Demo…

大数据计算基础真题回忆

转载学长20 21的真题 转载链接 注:每年的课件可能会有更改,内容不一样,所以读者复习的时候以所在年份的课件为准 2020 ​ 2021 笔者2023秋 2023 都是大题,没有选择题。 改进的近似算法中,结合具体的例子说明&am…

【Linux】Linux系统编程——Linux命令解析器

【Linux】Linux系统编程——Linux命令解析器 什么是Linux 命令解析器? Linux 命令解析器,通常被称为 shell,是 Linux 操作系统中的一个关键组件。它充当用户和系统内核之间的接口,允许用户通过输入命令来控制和管理操作系统和应…

计算机丢失mfc140.dll怎么办?解决mfc140.dll缺失的3种方法分享

计算机丢失mfc140.dll怎么办?在使用微软办公软件的时候,可能会弹出一个错误提示框说“找不到mfc140.dll,无法继续执行代码”。为了不影响工作效率,我们可能需要亲自动手尝试修复这一问题。以下是一些mfc140.dll缺失的3种方法相关介…

LED显示屏控制卡常见问题详解

LED显示屏控制卡是LED图文显示屏的关键组件,主要负责接收来自计算机串行口的图像显示信息,将其放入帧存储器,并按照分区驱动方式生成LED显示屏所需的串行显示数据和扫描控制时序。带你5分钟了解LED显示屏控制系统。本文将针对LED显示屏控制卡…

2024最新外贸建站:ChemiCloud主机购买使用及自建外贸独立站教程

随着电商平台竞争的加剧,许多外贸从业者意识到减少对平台依赖的重要性,并选择搭建自己的外贸独立站来获得更多的控制权和灵活性。即使是没有建站基础的新手,也可以通过学习建站来实现这一目标。下面是一个适用于新手的外贸建站教程&#xff0…

Spring AOP概念

什么是 AOP ? AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP 是 OOP 的延续,是软件开发中的一个热点,也是 Spring …

请问下大家PMP证书值得考嘛?

做项目的去考,项目经理、产品经理这些,或者有往项目管理领域发展的去考。其他行业有空可以学习下 不一定要考证了。 PMP证书更多的是“敲门砖”作用,大部分公司招聘的门槛都要去了这个证书。 当然现在PMP管理模式也很热门,各大企…

数字IC芯片设计实现 | 时序Timing Signoff check_timing检查解析

今天分享在数字IC芯片设计实现做timing signoff阶段必须要看的report。check_timing的报告必须是clean的,否则芯片回来大概率是废片!!!实际上一堆公司的芯片败在不看这个report了。 我们知道primetime(简称PT)做时序检查是基于我…

深入PostgreSQL:高级函数用法探索

写在开头 在 PostgreSQL 中,函数是数据库开发和管理中强大而灵活的工具。通过深入了解高级函数用法,我们可以更有效地利用 PostgreSQL 的功能。在本文中,我们将探讨一些看起来比较高级的 PostgreSQL 函数用法,包括窗口函数、自定义聚合函数、JSONB 类型函数、全文搜索、PL…

YACS(上海计算机学会竞赛平台)2022年12月月赛——星号三角阵(二)

题目描述 给定一个整数 n,输出一个 n 行 n 列的星号三角阵,直角位于图形的左上角。例如当 n4 时,输出 **** *** ** *输入格式 单个整数表示 n。 输出格式 共 n 行:表示一个星号三角阵。 数据范围 1≤n≤100 样例数据 输入…

数据库参数 PGA_AGGREGATE_LIMIT 限制进程大小

在自动化 PGA 内存管理模式下,Oracle 数据库通过动态控制分配到工作区的 PGA 内存量来尝试遵从 PGA_AGGREGATE_TARGET 值。但是,有时因为以下原因,PGA 内存使用量可能会超过 PGA_AGGREGATE_TARGET 设置: PGA_AGGREGATE_TARGET 设置…

localhost和127.0.0.1的区别是什么

今天在网上逛的时候看到一个问题,没想到大家讨论的很热烈,就是标题中这个: localhost和127.0.0.1的区别是什么? 前端同学本地调试的时候,应该没少和localhost打交道吧,只需要执行 npm run 就能在浏览器中打…

用python实现旭日图

旭日图(Sunburst Chart)是一种可视化数据的方式,它展示了层次结构和嵌套关系。在旭日图中,中心点代表最高级别,然后向外展开,表示数据中的层次结构。 Python中有一个名为pyecharts的库,可以用来…

MySql数据库备份和恢复

windows下操作 备份exp.bat内容如下 echo offcd C:\Program Files\MySQL\MySQL Server 8.0\binmysqldump -uroot -p12345678 -R dayreport > D:\bk\20230420\dayreport_20230420.sqlmysqldump -uroot -p12345678 -R ddm_am > D:\bk\20230420\ddm_am_20230420.sqlmysqld…