简介

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. 【mysql】用navicat无法连接mysql时解决方法

    1.进入数据库 2.输入 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;

  2. python学习 0 python简介

    一.Python简介 python是一门简单易学又功能强大的编程语言.它具有高效的高级数据结构和简单而有效的面向对象编程的特性.python优雅的语法和动态类型.以及其解释性的性质,使它在许多领域和大 ...

  3. Linux网络安全篇,认识防火墙(三),TCP Wrappers

    1.防火墙设置文件 任何以xinetd管理的服务都可以通过 /etc/hosts.allow /etc/hosts.deny 这两个文件来设置防火墙(针对源IP或域进行允许或操作的设置). 其实/et ...

  4. Linux C++ 网络编程学习系列(1)——端口复用实现

    Linux C++ 网络编程学习系列(1)--端口复用实现 源码地址:https://github.com/whuwzp/linuxc/tree/master/portreuse 源码说明: serv ...

  5. 王者荣耀英雄全皮肤4K高清大图,python爬虫帮你保存下来

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取t.cn ...

  6. 引用传参与reference_wrapper

    本文是<functional>系列的第3篇. 引用传参 我有一个函数: void modify(int& i) { ++i; } 因为参数类型是int&,所以函数能够修改传 ...

  7. LeetCode#160-Intersection of Two Linked Lists-相交链表

    一.题目 编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], l ...

  8. 新手想掌握Python技能需要众多Python项目练习,适合项目有哪些?

    适合新手练习的Python项目有哪些?简单易上手的Python项目汇总:Web 项目设计:内容聚合器.正则表达式查询工具.网址缩短.便利贴.功能.测验.GUI 项目设计:MP3 播放器.闹铃提醒工具. ...

  9. SK-learn实现k近邻算法【准确率随k值的变化】-------莺尾花种类预测

    代码详解: from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split fr ...

  10. linux上Docker安装gogs私服亲测(详解)

    一.前言 有网友问我为什么要使用私服,可能大部分人都不是太懂,网上那么多存储仓库而且好用方便,但是你想过没有如果企业中的项目,放在人家的仓库上这个安全性不是太好,所以说一般企业都会有自己的私服.本章教 ...