首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >设计模式 -- 模板方法模式

设计模式 -- 模板方法模式

作者头像
xy_ss
发布于 2023-11-22 01:27:34
发布于 2023-11-22 01:27:34
19200
代码可运行
举报
文章被收录于专栏:浮躁的喧嚣浮躁的喧嚣
运行总次数:0
代码可运行

场景

烹饪中,一般工序步骤为,准备食材、烹饪食材、上餐三个步骤,在这三个步骤中准备食材和上餐大同小异,最大区别在于第二步烹饪食材,是兰州牛肉面还是山西刀削面

问题来了 在开发中,有时也有此类问题,某方法实现需要多个步骤,其中有些步骤是固定的,有些步骤是不固定的

问题改进 使用模板方法模式来设计,一方面可以提高了代码的复用性,另一方面还可以利用面向对象的多态性,在运行时选择一种具体子类,实现完整的烹饪方法,提高系统的灵活性和可扩展性

表述 (行为型模式)

定义一个操作中算法的框架,而将一些步骤延迟到子类中,模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

模板方法模式是一种基于继承的代码复用技术,它是一种类行为型模式。

其基本思想是抽象类提供一个称之为“模板”的方法,在这个方法中调用一些复杂流程的实现步骤,在这个方法中调用的基本步骤由其子类来重载,从而使得相同的算法框架可以有不同的执行结果

模板方法模式类图

模板方法模式类图

  • AbstractClass(抽象类):在抽象类中定义了一系列基本操作,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法
  • ConcreteClass(具体子类):它是抽象类的子类,用于实现在抽象类中声明的基本操作
  • 模板方法:定义在抽象类中,把基本操作方法组合在一起形成一个总算法
  • 抽象方法:定义在抽象类中,其具体实现在具体子类中实现
  • 具体方法:重载父类中的抽象方法并加以实现
  • 钩子方法:由一个抽象类声明,子类实现,其子类可能会加以扩展,通常在父类中会给出一个空实现

优点

  • 在父类中声明一个基本方法,由子类实现,在子类实现时并不会改变算法中步骤的执行顺序
  • 代码复用性强
  • 不同子类可以提供基本方法的不同实现,跟换子类很方便,符合单一职责原则和开闭原则

缺点

需要为每个基本方法的不同实现提供一个子类,如父类中可变的基本方法太多,将会导致类的个数增加,系统更加庞大

使用场景

  • 需要一次性实现算法的不变部分,并将可变的行为留给子类来实现
  • 子类的共同行为应该被提取出来放到公共类,以避免代码重复
  • 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制

示例(需求V1:不带钩子方法,需求V2:带钩子方法)

需求V1:做俩份面条,一份是山西刀削面,一份是兰州牛肉面

//抽象类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Noodles {
    
    func flour() {
        print("准备面粉")
    }
    
    func addMeat() {
        
    }
    
    func addCondiments() {
        
    }
    
    func serve() {
        print("上菜")

    }

    func make() {
        self.flour()
        self.addMeat()
        self.addCondiments()
        self.serve()
    }
}

//具体子类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class ShanxiSlicedNoodles : Noodles {
    
    override func addMeat() {
        self.addPork()
    }
    
    override func addCondiments() {
        self.addSoupStock()
    }
    
    func addPork() {
        print("加猪肉")
    }
    
    func addSoupStock() {
        print("加高汤")
    }
}

class LanzhouBeefNoodles : Noodles{
    override func addMeat() {
        self.addBeef()
    }
    
    override func addCondiments() {
        self.addStock()
    }
    
    func addBeef() {
        print("加牛肉")
    }
    
    func addStock() {
        print("加汤")
    }
}

客户端

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var noodles:Noodles?
noodles = ShanxiSlicedNoodles.init()
noodles?.make()
noodles = LanzhouBeefNoodles.init()
noodles?.make()

//log:
//准备面粉
//加猪肉
//加高汤
//上菜

//准备面粉
//加牛肉
//加汤
//上菜

需求V2:在兰州牛肉面中需要再加点肉

必要时子类可以扩展父类的方法,这个方法叫作“钩子”,默认的钩子方法是个空实现,所以我们在抽象类中添加一个extraStep(),并且在serve()前调用

抽象类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Noodles {
    
    func flour() {
        print("准备面粉")
    }
    
    func addMeat() {
        
    }
    
    func addCondiments() {
        
    }
    
    func extraStep() {
        
    }
    
    func serve() {
        print("上菜")

    }

    func make() {
        self.flour()
        self.addMeat()
        self.addCondiments()
        self.extraStep()
        self.serve()
    }
}

具体子类(重载extraStep) 不管你要加多少步骤,可随意的添加在extraStep()中,这个方法被调用时,其中的所有操作都可被调用,而且不用修改父类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class LanzhouBeefNoodles : Noodles{
    override func addMeat() {
        self.addBeef()
    }
    
    override func addCondiments() {
        self.addStock()
    }
    
    override func extraStep() {
        self.addBeef()
    }
    
    func addBeef() {
        print("加牛肉")
    }
    
    func addStock() {
        print("加汤")
    }
}

客户端调用不变,但是输出log中已经加了份牛肉

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//准备面粉
//加牛肉
//加汤
//加牛肉
//上菜
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-08-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
设计模式-模板方法模式
在实现模板方法模式时,开发抽象类的软件设计师和开发具体子类的软件设计师之间可以进行协作。一个设计师负责给出一个算法的轮廓和框架,另一些设 计师则负责给出这个算法的各个逻辑步骤。实现这些具体逻辑步骤的方法即为基本方法,而将这些基本方法汇总起来的方法即为模板方法,模板方法模式的 名字也因此而来。下面将详细介绍模板方法和基本方法:
码哥字节
2021/07/27
2950
JAVA 设计模式 模板方法模式
根据文章内容撰写该文的摘要总结
静默虚空
2018/01/05
6840
JAVA 设计模式 模板方法模式
【设计模式】Java设计模式之模板方法模式
我们先这样来想象一个生活中的场景, 就是我们在银行柜台进行办理业务的时候,会进行这几步: Step1:进门取号 Step2:填写单据 Step3:等待叫号 Step4:窗口办理
谙忆
2021/01/21
3770
【设计模式】Java设计模式之模板方法模式
模板方法模式 Template method 行为型 设计模式(二十六)
相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为你的内容。 
noteless
2018/12/28
5550
设计模式----模板方法模式
模板方法模式: 在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模版方法使子类在不改变算法结构的情况下,重新定义算法中的某些步骤。 模板方法模式的结构: 抽象类:实现了模板方法,定义了算法的骨架。 具体类:实现抽象类中的抽象方法,已完成完整的算法。 这个模式是用来创建一个算法的模板。这个模板将算法定义为一组步骤,其中任何步骤都可以是抽象的,由子类负责实现。很多框架都是采用模板方法模式。 示例:星巴兹冲泡咖啡和茶的步骤如下: 咖啡冲泡法: 把水煮沸 用沸水冲泡咖啡
SuperHeroes
2018/05/30
4640
TypeScript 设计模式之模板方法
模板方法模式是一种只需使用继承就可以实现的非常简单的模式。模板方法模式由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类。通常在抽象父类中封装了子类的算法框架,也包括实现一些公共方法以及封装子类中所有方法的执行顺序。子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法。
阿宝哥
2020/02/13
7140
「设计模式 JavaScript 描述」模板方法模式
在 JavaScript 开发中用到继承的场景其实并不是很多,但这不代表继承在 JavaScript 里没有用武之地,虽然没有真正的类和继承机制,但我们可以通过原型 prototype 来变相地实现继承。
用户8921923
2022/10/24
3290
06-01-设计模式 模板方法模式
选材、浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的(红豆、花生豆浆。。。)
彼岸舞
2022/05/28
1890
06-01-设计模式 模板方法模式
设计模式——模板方法模式
● 1.定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。
蜻蜓队长
2018/08/03
4470
设计模式——模板方法模式
Java设计模式-模板方法模式
Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template
美的让人心动
2019/06/25
7050
模板方法模式.
我们打算定义一个咖啡因饮料冲泡流程,把流程中相同的步骤放在一起,同时,不同的饮料还能有自己的具体实现。
JMCui
2018/12/28
4860
设计模式 | 模板方法模式及典型应用
在程序开发中,经常会遇到这种情况:某个方法要实现的算法需要多个步骤,但其中有一些步骤是固定不变的,而另一些步骤则是不固定的。为了提高代码的可扩展性和可维护性,模板方法模式在这种场景下就派上了用场。
小旋锋
2019/01/21
1.3K0
一天一个设计模式:模板方法模式
  模板方法模式是类的行为模式,准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的意思。
用户1134788
2018/12/10
4170
一天一个设计模式:模板方法模式
javascript设计模式七:模板方法模式
模板方法模式,是一种典型的通过封装变化提高系统扩展性的设计模式。在传统的面向对象语言中,一个运用了模板方法模式的程序中,子类的方法种类和执行顺序都是基本不变的,所以把这部分逻辑抽象到父类的模板方法中。而子类的方法具体怎么实现则是可变的,于是我们把这部分变化的逻辑封装到子类中。通过增加新的子类,就能给系统增加新的功能,并不需要改动抽象父类以及其他子类,这符合开放-封闭原则。
前端_AWhile
2019/08/29
3670
Java设计模式(十四)----模板方法模式
模板方法模式 一、概述 二、结构 三、具体案例 四、优缺点和设计思想 一、概述 模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意 二、结构  模板方法模式是所有模式中最为常见的几个模式之一,是基于继承的代码复用的基本技术。   模板方法模式需要开发抽象类和具体
汤高
2018/01/11
9750
Java设计模式(十四)----模板方法模式
模板方法设计模式解读
编写制作豆浆的程序,说明如下: 1) 制作豆浆的流程 选材--->添加配料--->浸泡--->放到豆浆机打碎 2) 通过添加不同的配料,可以制作出不同口味的豆浆 3) 选材、浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的 4) 请使用 模板方法模式 完成 (说明:因为模板方法模式,比较简单,很容易就想到这个方案,因此就直接使用,不再使用传统的方案来引出模板方法模式 )
一个风轻云淡
2023/10/15
1530
模板方法设计模式解读
设计模式 ( 十九 ) 模板方法模式Template method(类行为型)
设计模式 ( 十九 ) 模板方法模式Template method(类行为型)
黄规速
2022/04/14
5950
设计模式 ( 十九 ) 模板方法模式Template method(类行为型)
掌握设计模式:深入理解模板方法模式
设计模式是面向对象编程中的重要概念,它提供了一种解决常见问题的通用方法。在本文中,我们将深入探讨模板方法模式,探讨它的定义、应用场景以及如何使用示例代码实现。
coderidea
2023/11/20
2770
掌握设计模式:深入理解模板方法模式
Java设计模式-模板方法模式
说到模板方法模式,它可能是一个让我们深入骨髓而又不自知的模式了,因为它在我们开发过程中会经常遇到,并且也非常简单。只不过,很多时候我们并不知道它就是模板方法模式而已。不负责任的说,当我们用到override关键字重写父类方法的时候,十有八九就跟模板方法模式有关了。
宁在春
2022/10/31
3690
Java设计模式-模板方法模式
设计模式之模板方法模式(二)
上一篇我们已经学会了模板方法模式,这次我们继续来深入学习下。毕竟学会只是第一步,还有更进一步的学习和深入等着我们呢。
程序员小跃
2019/12/26
5500
相关推荐
设计模式-模板方法模式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验