简介

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. linux中忘记了mysql的root用户的密码怎么办?

    1.vim /etc/my.cnf skip-grant-tables  #取消此行的注释 2.重启mysql systemctl restart mysqld 3.mysql 登陆mysql mys ...

  2. Java第十二天,权限修饰符

    Java当中权限修饰符共有四种.分别是public.protected.(default).private. 注:YSE代表可访问,NO代表不可访问.   同一个类 同一个包,非继承 不同的包,有继承 ...

  3. 三、ARP协议和ICMP协议

    一.ARP协议 网络设备有数据要发送到另一台网络设备时,必须要知道对方的网络层地址(IP).IP地址由网络层来提供,但是仅有IP地址是不够的,IP数据报文必须封装成帧才能通过数据链路进行发送.数据帧必 ...

  4. spark sql createOrReplaceTempView registerTempTable

    createOrReplaceTempView2.x版本以上. registerTempTable1.5.x val data1 = dataSelect1(sqlContext, sparkMode ...

  5. 聊一聊深拷贝和浅拷贝(JS)

    在 JS 中数据类型分为值类型和引用类型,对于值类型,变量中存放的是具体的值,而对于引用类型,变量中存放的是地址. 对于值类型: const a = 3; let b = a; b = 4; cons ...

  6. Gun N' Rose Team Review

    一看到这个项目就被他的功能给吸引了.回忆起以前看到一个东西很新奇想去网上查询它是什么,但是又不知道应该怎样去描述它,于是在搜索引擎的输入框中键入.删除.键入.删除的可笑经历的时候,我就越发感觉到这个a ...

  7. Java - window下环境配置

    JDK下载 官网:https://www.oracle.com/java/technologies/javase-jdk8-downloads.html 百度网盘: 链接:https://pan.ba ...

  8. 利用Putty建立SSH的tunnels访问内网资源

    适用场景访问阿里或者腾讯云只针对内网开放的资源. 本文以SQLSERVER 举例 举例你的内网 SQLSERVER的访问地址是192.168.33.88 . 你的Microsoft SQL Serve ...

  9. 19.SpringCloud实战项目-SpringCloud整合Alibaba-Nacos配置中心

    SpringCloud实战项目全套学习教程连载中 PassJava 学习教程 简介 PassJava-Learning项目是PassJava(佳必过)项目的学习教程.对架构.业务.技术要点进行讲解. ...

  10. java面试题(一年工作经验)的心得

    看面试题 正常人第一步肯定都会看面试题,我也不例外,在看的过程中,我发现有些文章写的不错,对我帮助不小值得推荐,如下: Java面试题全集(上) 很多基础的东西,建议先看. 各大公司Java后端开发面 ...