瑞幸咖啡还是星巴克,一杯下午茶让我明白 设计模式--模板方法模式(Template Method Pattern)
简介
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) 实际上是封装了一个固定流程,该流程由几个步骤组成,具体步骤可以由子类进行不同实现,从而让固定的流程产生不同的结果。
意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法模式实际上是所有模式中最为常见的几个模式之一,而且很多人可能使用过模板方法模式而没有意识到自己已经使用了这个模式。模板方法模式是基于继承的代码复用的基本技术,模板方法模式的结构和用法也是面向对象设计的核心。模板方法的本质:抽象封装流程,具体进行实现
模版方法模式需要开发抽象类和具体子类的设计师之间的协作。
- 一个设计师负责给出一个算法的轮廓和骨架
- 另一些设计师则负责给出这个算法的各个逻辑步骤。
- 代表这些具体逻辑步骤的方法称做基本方法(primitive method)
- 将这些基本方法总汇起来的方法叫做模版方法(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)的更多相关文章
- 如何获取(GET)一杯咖啡——星巴克REST案例分析
英文原文:How to GET a Cup of Coffee 我们已习惯于在大型中间件平台(比如那些实现CORBA.Web服务协议栈和J2EE的平台)之上构建分布式系统了.在这篇文章里,我们将采取另 ...
- 杂项-公司:星巴克百科-un
ylbtech-杂项-公司:星巴克百科 星巴克(Starbucks)是美国一家连锁咖啡公司的名称,1971年成立,是全球最大的咖啡连锁店,其总部坐落美国华盛顿州西雅图市.星巴克旗下零售产品包括30多款 ...
- pyecharts实现星巴克门店分布可视化分析
项目介绍 使用pyecharts对星巴克门店分布进行可视化分析: 全球门店分布/拥有星巴克门店最多的10个国家或地区: 拥有星巴克门店最多的10个城市: 门店所有权占比: 中国地区门店分布热点图. 数 ...
- 【分享】纯jQuery实现星巴克官网导航栏效果
前言 大冬天的没得玩,只能和代码玩. 所以就无聊研究了一下星巴克官网,在我看来应该是基本还原吧~ 请各位大神指教! 官网效果图 要写的就是最上方的会闪现的白色条条 效果分析 1.在滚动条往下拉到一定距 ...
- 【方法】纯jQuery实现星巴克官网导航栏效果
前言 大冬天的没得玩,只能和代码玩. 所以就无聊研究了一下星巴克官网,在我看来应该是基本还原吧~ 请各位大神指教! 官网效果图 要写的就是最上方的会闪现的白色条条 效果分析 1.在滚动条往下拉到一定距 ...
- pandas实战——对星巴克数据的分析
一.实验对象 实验对象为星巴克在全球的门店数据,我们可以使用pandas对其进行简单的分析,如分析每个国家星巴克的数量,根据门店数量对国家进行排序等. 二.数据分析 1.读取数据并获取数据行列数 首先 ...
- 《Head First 设计模式》之模板方法模式——冲泡咖啡和茶
模板方法模式(Template) ——在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 好莱坞原则:别调用(打电话给 ...
- 使用bs4中的方法爬取星巴克数据
import urllib.request # 请求url url = 'https://www.starbucks.com.cn/menu/' # 模拟浏览器发出请求 response = urll ...
- 深入浅出设计模式——模板方法模式(Template Method Pattern)
模式动机 模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一.在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中.在模板方法模式 ...
随机推荐
- 适用于 Mpvue 的微信小程序富文本解析自定义组件
废话不多说,直接上方法: 首先 npm 安装 mpvue-wxparse npm i mpvue-wxparse 接下来:使用 <template> <div> <wxP ...
- uni-app在线引入阿里字体图标库
第一步 在app.vue中引入阿里字体图标库 第二步 在任意页面使用就可以了 <view class="item" v-for="(value,index) in ...
- 十年测试老鸟告诉你--自动化测试选JAVA还是选Python--写给还在迷茫中的朋友
一.前言 Python和Java哪个更适合做自动化测试?这是很多测试工程师从功能跨入自动化纠结的问题,今天测试老鸟来带大家详细分析一下!写给还在迷茫中的朋友! 首先可以确认的是提出这个问题的肯定是一个 ...
- C#多线程系列(1):Thread
目录 1,获取当前线程信息 2,管理线程状态 2.1 启动与参数传递 2.1.1 ParameterizedThreadStart 2.1.2 使用静态变量或类成员变量 2.1.3 委托与Lambda ...
- 《面试经典系列》- SpringMVC原理及工作流程
前言 SpringMVC 作为 MVC 的开源框架,现在依旧是不少项目使用的重点框架.SpringMVC = Struts2 + Spring,SpringMVC就相当于 Struts2 + Spri ...
- mysql 单机多实例配置
如果你想在一台机器上进行主从配置实验,本篇可以帮助你实现愿望 [client] #password = your_password port = 3306 socket = /tmp/mysql.so ...
- web中拖拽排序与java后台交互实现
一.业务需求 1,在后台的管理界面通过排序功能直接进入排序界面 2,在排序界面能够人工的手动拖动需要排序的标题,完成对应的排序之后提交 3,在app或者是前端就有对应的排序实现了 二.页面展示 将整体 ...
- Android 程序代码进行代码混淆
1.在Eclipse项目包下的project.properties文件中加入proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt ...
- 远程登录redis
没想到吧,我居然已经摸到了redis. 远程登录redis redis-cli -h 127.0.0.1 -p 6379 ip地址和端口记得换成自己的
- python selenium模块 xpath定位
''' 附w3xpath语法地址 https://www.w3school.com.cn/xpath/xpath_syntax.asp 总结: 返回匹配到所有符合条件的第一个节点,对象是 <cl ...