1. UML类图简介
  2. 设计模式的分类
  3. 面向对象的设计原则
  4. python设计模式【1】-单例模式
  5. python设计模式【2】-工厂模式
  6. python设计模式【3】-门面模式
  7. python设计模式【4】-代理模式
  8. python设计模式【5】-观察者模式
  9. python设计模式【6】-命令模式
  10. python设计模式【7】-模板方法模式
  11. python设计模式【8】-模型·视图·控制器-复合模式
  12. python设计模式【9】-状态模式

了解模板方法设计模式

模板方法模式适用于以下场景:

1、当多个算法或类实现类似或相同逻辑的时候

2、在子类中实现算法有助于减少重复代码的时候

3、可以让子类利用覆盖实现行为来定义多个算法的时候

模板方法模式的主要意图:

1、使用基本操作定义算法的框架;

2、重新定义子类的某些操作,而无需修改算法的结构;

3、实现代码重用并避免重复工作

4、利用通用接口或实现

模板方法模式使用以下术语——AbstractClass、ConcreteClass、TemplateMethod和Client;

1、AbstractClass:声明一个定义算法步骤的接口

2、ConcreteClass:定义子类特定的步骤

3、template_method():通过调用步骤方法来定义算法

以下是一个代码示例,展示了该模式中所有参与者的关系:

from abc import ABCMeta, abstractmethodclass AbstractClass(metaclass=ABCMeta):def __init__(self):pass@abstractmethoddef operation1(self):pass@abstractmethoddef operation2(self):passdef template_method(self):print("定义算法,operation1与operation2")self.operation2()self.operation1()class ConcreteClass(AbstractClass):def operation1(self):print("My Concrete Operation1")def operation2(self):print("Operation2 remains same")class Client(object):def main(self):self.concreate = ConcreteClass()self.concreate.template_method()client = Client()
client.main()

现在假设我们为IOS设备开发自己的交叉编译器并运行程序。

首先开发一个抽象类(编译器),来定义编译器的算法。编译器执行的操作是收集由程序语言编写的源代码,然后编译成目标代码(二进制格式)。我们将这些步骤定义为collect_source()和compile_to_object()抽象方法,同时还定义了负责执行程序的run()方法。该算法是由compile_and_run()方法来定义的,它通过内部调用collect_source()、compile_to_object()和run()方法来定义编译器的算法。然后让具体类IOSCompiler实现抽象方法,在IOS设备上编译并运行Swift代码。

下面的Python代码用于实现模板方法设计模式:

from abc import ABCMeta, abstractmethodclass Compiler(metaclass=ABCMeta):@abstractmethoddef collect_source(self):pass@abstractmethoddef compile_to_object(self):pass@abstractmethoddef run(self):passdef compile_and_run(self):self.collect_source()self.compile_to_object()self.run()class IOSCompiler(Compiler):def collect_source(self):print("收集源码")def compile_to_object(self):print("编译源码")def run(self):print("运行程序")ios = IOSCompiler()
ios.compile_and_run()

生活中的模板方法模式

想象一个旅行社的例子,它们定义了各种旅行线路,并提供度假套装行程。一个行程套餐本质上是你作为客户允诺的一次旅行。旅行还涉及一些详细信息,如游览的地点、交通方式和旅行有关的其他因素。当然,同样的行程可以根据客户的需求进行不同的定制。这种情况下,模板方法模式很适合;

设计注意事项:

1、对于上述场景,我们应该创建一个定义旅行的AbstractClass接口

2、旅行应包含多个抽象方法,定义所使用的交通方式,在第一天、第二天和第三天所游览的地点(假设这是一个为期三天的旅行),并定义回程

3、模板方法itinerary()将实际定义该旅行的行程

4、我们应该定义ConcreteClasses,以帮助我们根据客户的需要对旅行进行相应的定制

我们从抽象类开始,即Trip:

1、抽象对象由Trip类表示。他是一个接口,定义了不同日子使用的交通方式和参观的地点等细节

2、set_transport是一个抽象方法,它由ConcreteClass实现,作用是设置交通的方式;

3、day1()、day2()、day3()抽象方法定义了特定日期所参观的地点

4、itierary()模板方法创建完整的行程。旅行的序列为,首先定义交通模式,然后每天参观的地点,以及return_home

代码如下:

from abc import ABCMeta, abstractmethodclass Trip(metaclass=ABCMeta):@abstractmethoddef set_transport(self):pass@abstractmethoddef day1(self):pass@abstractmethoddef day2(self):pass@abstractmethoddef day3(self):pass@abstractmethoddef return_home(self):passdef itinerary(self):self.set_transport()self.day1()self.day2()self.day3()self.return_home()

我们还要开发了代表具体类的某些类:

1、在本例中,我们主要有两个实现Trip接口的具体类:VeniceTrip和MaldivesTrip;

2、这两个具体类代表游客根据他们的选择和兴趣所进行的两次不同的旅行

3、VeniceTrip和MaldivesTrip都实现了set_transport()、day1()、day2()、day3()和return_home()

class VeniceTrip(Trip):def set_transport(self):print("乘船从大运河走")def day1(self):print("叹息桥")def day2(self):print("圣马可广场")def day3(self):print("凤凰歌剧院")def return_home(self):print("威尼斯返回")class MaldivesTrip(Trip):def set_transport(self):print("飞机")def day1(self):print("日光浴")def day2(self):print("潜水")def day3(self):print("欣赏海洋生物")def return_home(self):print("马尔代夫返回")

现在,让我们来考察一些旅行社和希望度过一个愉快的游客:

1、TravelAgency类代表该示例中的Client对象

2、它定义了arrange_trip()方法,让客户选择历史旅行或者海滩旅行

3、根据旅游者的选择,相应的类将被实例化

4、这个对象然后调用itinerary()模板方法,并根据客户的选择为游客安排相应的旅行

class TravelAgency(object):def arrange_trip(self):choice = input("historical or beach")if choice == "historical":self.trip = VeniceTrip()self.trip.itinerary()if choice == "beach":self.trip = MaldivesTrip()self.trip.itinerary()TravelAgency().arrange_trip()

模板方法模式——钩子

钩子是在抽象类中声明的方法,它通常被赋予一个默认实现。钩子背后的思想是为子类提供按需钩取算法的能力。但是它并不强制子类使用钩子,它可以很容易地忽略这一点

好莱坞原则与模板方法

好莱坞原则是一种设计原则,即不要给我们打电话,我们会打给你。它来自好莱坞哲学,如果有适合演员的角色,影棚会给演员打电话。

在面向对象的世界中,我们允许低层组件使用好莱坞原则将自己挂入系统中,然而,高层组件确定底层系统的使用方式,以及何时需要它们。换句话说,高层组件对待底层组件的方式也是不要给我们打电话,我们会打电话给你。

这涉及模板方法模式,在这个意义上,它是高级抽象类,它安排定义算法的步骤。根据算法的工作方式,通过调用底层类来定义各个步骤的具体实现。

模板方法模式的优点和缺点

优点:

1、没有代码重复

2、由于模板方法模式使用继承而不是合成,因此能够对代码进行重用。所以,只有为数不多的几个方法需要重写

3、灵活性允许子类决定如何实现算法中的步骤

缺点:

1、调试和理解模板方法模式中的流程程序序列有时会令人困惑。你最终实现的方法可能是一个不应该实现的方法,或根本没有实现抽象的方法。文档和严格的错误处理必须由程序员完成

2、模板框架的维护可能是一个问题,因为任何层次的变更都可能对实现造成干扰。因此使用模板方法模式可能会使维护变的异常痛苦


参考:

《python设计模式》(第2版)https://www.epubit.com/

python设计模式【7】-模板方法模式相关推荐

  1. 细说Python设计模式之模板方法模式(封装算法)

    文章目录 定义模板方法模式 适用场景 日常例子理解该模式 了解模板方法设计模式 模板方法模式的UML类图 现实中的模板方法模式 模板方法模式--钩子 好莱坞原则与模板方法 模板方法的优缺点 问答 定义 ...

  2. Python设计模式(四) -- 模板方法模式

    模板方法模式 定义 定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式.让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤 适用场景: 事务处理的步骤具有共性,只是具体实施,根据 ...

  3. Python设计模式之模板方法模式实例详解

    1.模板方法模式定义 定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定的步骤. 子类实现的具体方法叫作基本方法,实现对基本方法高度的框 ...

  4. Python设计模式-装饰器模式

    Python设计模式-装饰器模式 代码基于3.5.2,代码如下; #coding:utf-8 #装饰器模式class Beverage():name = ""price = 0.0 ...

  5. Python设计模式-中介者模式

    Python设计模式-中介者模式 代码基于3.5.2,代码如下; #coding:utf-8 #中介者模式class colleague():mediator = Nonedef __init__(s ...

  6. Python设计模式-职责链模式

    Python设计模式-职责链模式 代码基于3.5.2,代码如下; #coding:utf-8 #职责链模式class Handler():def __init__(self):self.success ...

  7. Python设计模式-享元模式

    Python设计模式-享元模式 基于Python3.5.2,代码如下 #coding:utf-8class Coffee:name = ""price = 0def __init_ ...

  8. python的编程模式-Python设计模式之状态模式原理与用法详解

    本文实例讲述了Python设计模式之状态模式原理与用法.分享给大家供大家参考,具体如下: 状态模式(State Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类 ...

  9. python策略模式包含角色_详解Python设计模式之策略模式

    虽然设计模式与语言无关,但这并不意味着每一个模式都能在每一门语言中使用.<设计模式:可复用面向对象软件的基础>一书中有 23 个模式,其中有 16 个在动态语言中"不见了,或者简 ...

  10. 一篇博客读懂设计模式之---模板方法模式

    设计模式之模板方法模式: 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 简而言之就是:父类定义了骨架(调用哪些方法及其 ...

最新文章

  1. 加减法叫做什么运算_期中备考:数学运算定律、法则与顺序
  2. 使用 mysql workbench 建议
  3. Scala代码案例:判断一个年份是否是闰年
  4. python ctime函数_Python中的ctime()方法使用教程
  5. 计算机指令int,汇编入门学习笔记 (十二)—— int指令、端口
  6. vue-cil解决开发环境的跨域问题
  7. Springboot配置devtools实现热部署
  8. 目标检测 | 火焰烟雾检测论文(实验部分)
  9. 凸透镜成像实验软件_凸透镜成像模拟实验软件介绍
  10. 龙格库塔方法的原理和案例及MTATLAB编程
  11. 网站视频很卡怎么办?有没有免费的视频平台?使用阿里云OSS对象云存储+下行流量包解决网站文件/视频访问慢问题
  12. 模电四:基本放大电路
  13. 计算机桌面背景在哪里调整,电脑中怎么设置桌面背景
  14. 人人都在谈的 “数据驱动” 到底是什么?你确认自己做的是数据驱动吗?
  15. 低维空间到高维空间的映射
  16. 处女座与小姐姐(三)
  17. [Jzoj] 2197. 三核苷酸
  18. c语言中while中的判断语句为感叹号x时是什么意思?
  19. android 打开屏幕,Android打开屏幕
  20. 51CTO下载中心做活动

热门文章

  1. 浅析RFID仓库管理系统的功能
  2. Unity 音乐可视化
  3. 米尔科技调试串口转普通串口
  4. c#版本视频在线播放(通用播放器调用),支持avi,wmv,asf,mov,rm,ra,ram等
  5. iNFTnews | 回顾支付宝鲸探发展历程:是数藏的投机客还是引领者?
  6. 微信小游戏开发实战教程系列开启
  7. 消息队列 CMQ 七大功能实践案例
  8. Vim及NeoVim插件合集
  9. 阿里云ACP考试地点及考试时间安排
  10. 两台电脑usb直连 linux,两台电脑怎么传文件没有网线(两台电脑usb直连)