简介

Define the skeleton of an algorithm in an operation,deferring some

steps to subclasses.Template Method lets subclasses redefine certain

steps of an algorithm without changing the algorithm’s structure.

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

-----------------------------------------------------------------深入浅出的设计模式

  • 模板方法模式(Template Method Pattern) 实际上是封装了一个固定流程,该流程由几个步骤组成,具体步骤可以由子类进行不同实现,从而让固定的流程产生不同的结果。

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

  • 模板方法模式实际上是所有模式中最为常见的几个模式之一,而且很多人可能使用过模板方法模式而没有意识到自己已经使用了这个模式。模板方法模式是基于继承的代码复用的基本技术,模板方法模式的结构和用法也是面向对象设计的核心模板方法的本质:抽象封装流程,具体进行实现

  • 模版方法模式需要开发抽象类和具体子类的设计师之间的协作。

    1. 一个设计师负责给出一个算法的轮廓和骨架
    2. 另一些设计师则负责给出这个算法的各个逻辑步骤。
    3. 代表这些具体逻辑步骤的方法称做基本方法(primitive method)
    4. 将这些基本方法总汇起来的方法叫做模版方法(template method),这个设计模式的名字就是从此而来。

主要解决

当完成一个操作具有固定的流程时,由抽象固定流程步骤,具体步骤交给子类进行具体实现(固定的流程,不同的实现)。

优缺点

优点

  • 封装不变,扩展可变:父类封装了具体流程以及实现部分不变行为,其它可变行为交由子类进行具体实现;
  • 流程由父类控制,子类进行实现:框架流程由父类限定,子类无法更改;子类可以针对流程某些步骤进行具体实现;
  • 提取公共代码,便于维护

缺点

  • 抽象规定了行为,具体负责实现,与通常事物的行为相反,会带来理解上的困难(通俗地说,“父类调用了子类方法”);
  • 每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

使用场景

当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同的时候,我们通常要考虑用模板方法模式解决。

  • 多个子类有公有的方法,并且逻辑基本相同时;
  • 重要,复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现;
  • 重构时,模板方法模式 是一个经常使用的模式,把相同的代码抽取到父类,然后通过钩子函数约束其行为;

注意事项: 为防止恶意操作,一般模板方法都加上 final 关键词。

模式讲解

首先来看下 模板方法模式 的通用 UML 类图:



模板方法模式

从 UML 类图中,我们可以看到,模板方法模式 主要包含两种角色:

抽象模板(AbstractClass): 抽象模板类,定义了一套算法框架/流程;

具体实现(ConcreteClass): 具体实现类,对算法框架/流程的某些步骤进行了实现;

当然这只是书面上的定义,用起来你会发现,为什么变得很复杂,好像更难了一样,你也有很多疑问?

  • 在抽象类中只能定义抽象函数吗?

    不是!看使用场景第三条!
  • 每一个抽象子类都要具体实现吗?

    语法上是的,但逻辑上,可以Do nothing
  • 依据第一问,我能否对非抽象方法重写?

    当然,语法上可以,而且逻辑上也可以。

最后,设计模式给出的是一种设计框架,而不是条条框框,你需要用的是他真正优秀的地方!

开发实例



就一杯下午茶,我到底和咖啡还是喝茶,喝咖啡,瑞幸还是星巴克?:

抽象类:

abstract class AbstractClass {
protected void Boil_water() {
System.out.println("SpecificMethod:烧水,倒一杯热水");
/*
* 模板方法的抽象类中,也是可以定义具体方法的,
* 一般子类中都具备或大部分中都具备时,放到抽象父类中。
*/
}
// 需要子类必须实现的需要写成抽象类
protected abstract void Abstract_step1(); protected abstract void Abstract_step2(); protected void Drink() {
System.out.println("SpecificMethod:吹一吹再喝,别烫着!");
} // 声明为final方法,避免子类覆写
public final void After_Tea() {//来一杯下午茶吧
this.Boil_water();
this.Abstract_step1();
this.Abstract_step2();
this.Drink();
}
}

我要喝咖啡

class Concrete_Cof extends AbstractClass {

	@Override
// 具体实现,重写父类抽象方法
protected void Abstract_step1() {
System.out.println("把咖啡豆磨好,倒进杯子里");
} @Override
protected void Abstract_step2() {
System.out.println("加入方糖和奶精"); } }

我要喝茶

class Concrete_Tea extends AbstractClass {

	@Override
protected void Abstract_step1() {
System.out.println("把茶饼分开,放进杯子里"); } @Override
protected void Abstract_step2() {
//Do nothing
//可以写成这种什么都没有的,毕竟喝茶我什么都不加(手动狗头)
} }

我要喝奶茶


public class Concrete_MilkTea extends AbstractClass { protected void Boil_water() {
System.out.println("煮一杯热牛奶");
}
@Override
protected void Abstract_step1() { System.out.println("把茶饼分开,放进杯子里,过滤"); } @Override
protected void Abstract_step2() {
System.out.println("加入方糖和香精");
} }
class Client {
public static void main(String[] args) {
AbstractClass abc = new Concrete_Cof();
abc.After_Tea();
System.out.println("----------Next day-------------");
abc=new Concrete_Tea();
abc.After_Tea();
System.out.println("----------Next day-------------");
abc=new Concrete_MilkTea();
abc.After_Tea();
}
}

运行结果:



码字这么卖力,麻烦点个赞,点个关注,谢谢。

写在最后:

我叫风骨散人,名字的意思是我多想可以不低头的自由生活,可现实却不是这样。家境贫寒,总得向这个世界低头,所以我一直在奋斗,想改变我的命运给亲人好的生活,希望同样被生活绑架的你可以通过自己的努力改变现状,深知成年人的世界里没有容易二字。目前是一名在校大学生,预计考研,热爱编程,热爱技术,喜欢分享,知识无界,希望我的分享可以帮到你!

如果有什么想看的,可以私信我,如果在能力范围内,我会发布相应的博文!

感谢大家的阅读!

瑞幸咖啡还是星巴克,一杯下午茶让我明白 设计模式--模板方法模式(Template Method Pattern)的更多相关文章

  1. 如何获取(GET)一杯咖啡——星巴克REST案例分析

    英文原文:How to GET a Cup of Coffee 我们已习惯于在大型中间件平台(比如那些实现CORBA.Web服务协议栈和J2EE的平台)之上构建分布式系统了.在这篇文章里,我们将采取另 ...

  2. 杂项-公司:星巴克百科-un

    ylbtech-杂项-公司:星巴克百科 星巴克(Starbucks)是美国一家连锁咖啡公司的名称,1971年成立,是全球最大的咖啡连锁店,其总部坐落美国华盛顿州西雅图市.星巴克旗下零售产品包括30多款 ...

  3. pyecharts实现星巴克门店分布可视化分析

    项目介绍 使用pyecharts对星巴克门店分布进行可视化分析: 全球门店分布/拥有星巴克门店最多的10个国家或地区: 拥有星巴克门店最多的10个城市: 门店所有权占比: 中国地区门店分布热点图. 数 ...

  4. 【分享】纯jQuery实现星巴克官网导航栏效果

    前言 大冬天的没得玩,只能和代码玩. 所以就无聊研究了一下星巴克官网,在我看来应该是基本还原吧~ 请各位大神指教! 官网效果图 要写的就是最上方的会闪现的白色条条 效果分析 1.在滚动条往下拉到一定距 ...

  5. 【方法】纯jQuery实现星巴克官网导航栏效果

    前言 大冬天的没得玩,只能和代码玩. 所以就无聊研究了一下星巴克官网,在我看来应该是基本还原吧~ 请各位大神指教! 官网效果图 要写的就是最上方的会闪现的白色条条 效果分析 1.在滚动条往下拉到一定距 ...

  6. pandas实战——对星巴克数据的分析

    一.实验对象 实验对象为星巴克在全球的门店数据,我们可以使用pandas对其进行简单的分析,如分析每个国家星巴克的数量,根据门店数量对国家进行排序等. 二.数据分析 1.读取数据并获取数据行列数 首先 ...

  7. 《Head First 设计模式》之模板方法模式——冲泡咖啡和茶

    模板方法模式(Template) ——在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 好莱坞原则:别调用(打电话给 ...

  8. 使用bs4中的方法爬取星巴克数据

    import urllib.request # 请求url url = 'https://www.starbucks.com.cn/menu/' # 模拟浏览器发出请求 response = urll ...

  9. 深入浅出设计模式——模板方法模式(Template Method Pattern)

    模式动机 模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一.在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中.在模板方法模式 ...

随机推荐

  1. 从String 聊源码解读

    @ 目录 源码实现 构造方法 equals 其他方法 常见面试题 你真的了解String吗?之前一篇博客写jvm时,就觉得String可以单独拎出来写一篇博客,毕竟几乎所有的面试都是以String开始 ...

  2. Flask 入门(六)

    连接数据库 任何一门后端语言都可以连接数据库,python-flask也不例外 flask利用SQLAlchemy ORM连接数据库 接下来,我门来练习如何连接数据库: 1.首先,电脑上得有mysql ...

  3. 2020-3-3 20175110王礼博 《网络对抗技术》Exp1 PC平台逆向破解

    目录 1.实践目标与基础知识 2.直接修改程序机器指令,改变程序执行流程 3.通过构造输入参数,造成BOF攻击,改变程序执行流 4.注入Shellcode并执行 5.实验收获与感想 6.什么是漏洞?漏 ...

  4. 虚拟机安装windows sever2008

    1.打开并进行新建虚拟机 2.默认选择“典型” 3.选择“安装程序盘映像文件”,并‘浏览’选择本地的文件 4. 5.后面的默认选择即可,安装路径可自己修改 6.这一步的磁盘大小可自己修改的,这里先预设 ...

  5. 基于my-DAQ的温室迷你温室设计

    这是一个小项目,采用NI的my-DAQ做数据采集,需要采集的数据有温度(LM35),气体(MQ2),需要控制的设备有风扇.加热棒,另外还有光照亮度调节. 一.数据采集 1.LM35 LM35是模拟输出 ...

  6. O - Employment Planning HDU - 1158

    题目大意: 第一行一个n,表示共n个月份,然后第二行分别表示一个工人的聘请工资,月薪水,解雇工资.第三行是n个月每个月需要的工人的最少数目.然后求最少花费 题解: dp[i][j] 表示第i个月聘请j ...

  7. Scrapy学习-(1)

    Scrapy框架介绍 Scrapy是一个非常优秀的爬虫框架,基于python. 只需要在cmd运行pip install scrapy就可以自动安装.用scrapy-h检验是否成功安装 Scrapy部 ...

  8. testNG 预期异常、忽略测试、超时测试

    通过@Test 注解的参数值实现如下的几种测试 一.通过 @Test(expectedExceptions=异常类名) 参数实现到达 预期指定的异常效果 @Test(expectedException ...

  9. 【学习笔记】 $learn \ from \ failure \ ? ( 雾$

    \(1.\)变量名不要用 \(next\) ,在某些编译器里可能是关键词,可以用 \(nxt\) 代替 \(\\\) \(2.\)在判断某些条件时应该写成 flag = 条件 ? 1 : flag; ...

  10. 分析PE

    PE文件是Windows平台下可执行文件标准格式,浓缩了微软工程师的设计精华,历经40年依旧保持着原有的设计.分析PE文件对于研究Windows操作系统有着重要的实践意义,对于逆向分析有着重要的指导作 ...