示例

当我们设计一个类时,我们能明确它对外提供的某个方法的内部执行步骤,

但一些步骤,不同的子类有不同的行为时,我们该如何来设计该类?

下面以玩王者荣耀为例展开学习:

玩游戏首先需要初始化游戏,然后加载地图、加载角色、然后才能开始游戏,最后结束游戏

定义一个Game类:

public abstract class Game {

    public final void play () {
initialize();
loadMap();
loadRole();
startPlay();
endPlay();
} /** 初始化游戏 */
protected abstract void initialize(); /** 加载地图 */
protected abstract void loadMap(); /** 加载角色 */
protected abstract void loadRole(); /** 开始游戏 */
protected abstract void startPlay(); /** 结束游戏 */
protected abstract void endPlay();
}

上面类的实现类:

public class KingGlory extends Game {

    @Override
protected void initialize() {
System.out.println("王者荣耀正在初始化,请稍后。。。");
} @Override
protected void loadMap() {
System.out.println("正在加载王者峡谷地图。。。");
} @Override
protected void loadRole() {
System.out.println("正在加载角色鲁班七号。。。");
} @Override
protected void startPlay() {
System.out.println("开始玩王者荣耀。。。");
} @Override
protected void endPlay() {
System.out.println("结束王者荣耀游戏,保存数据。。。");
}
}

测试类:

public class Test {
public static void main(String[] args) {
Game game = new KingGlory();
game.play();
}
}

模板方法模式

定义

一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行

意图

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

主要解决问题

一些方法通用,却在每一个子类都重新写了这一方法

适用场景

1、有多个子类共有的方法,且逻辑相同。

2、重要的、复杂的方法,可以考虑作为模板方法

优缺点

优点:

1、封装不变部分,扩展可变部分。

2、提取公共代码,便于维护。

3、行为由父类控制,子类实现。

缺点:

每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞

类图:



涉及的角色:

  1. 抽象模板(AbstractTemplate)角色:定义了一个或多个抽象操作,以便让子类实现,这些抽象操作叫基本操作,它们是顶级逻辑的组成步骤;定义并实现了一个模板方法,这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现
  2. 具体模板(ContrateTemplate)角色:实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤;每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法的不同实现,从而使得顶级逻辑的实现各不相同

对应源码:

public abstract class AbstractTemplate {

    public void templateMethod() {
doOperation1(); doOperation2(); doOperation3();
} /** 基本方法,由子类实现 */
protected abstract void doOperation1(); /** 基本方法,由子类实现 */
protected abstract void doOperation2(); /** 基本方法,已经实现 */
private final void doOperation3(){
//do something......
}
}
public class ContrateTemplate extends AbstractTemplate {
@Override
protected void doOperation1() {
System.out.println("doOperation1......");
} @Override
protected void doOperation2() {
System.out.println("doOperation2......");
}
}

西天取经的九九八十一难

在《西游记》中,唐僧到西天取经途中所经历的八十一难,说到底,是观音菩萨所控制的一个项目,下面以上面场景为例,写一个小例子:

取经人所经历的劫难,每一步都是菩萨控制好的:

public abstract class LearnFromPeople {

    public final void westernCountry() {
firstHard();
secondHard();
thirdHard();
} /** 第一难 */
protected abstract void firstHard(); /** 第二难 */
protected abstract void secondHard(); /** 第三难 */
protected abstract void thirdHard();
}

唐僧去西天取经,继承了取经人这个抽象类,然后需要历经81难:

public class TangMonk extends LearnFromPeople {
@Override
protected void firstHard() {
System.out.println("金蝉遭贬第一难"); } @Override
protected void secondHard() {
System.out.println("出胎几杀第二难");
} @Override
protected void thirdHard() {
System.out.println("满月抛江第三难");
}
}

唐僧开始上路了:

public class Test {

    public static void main(String[] args) {
LearnFromPeople people = new TangMonk();
people.westernCountry();
}
}



需要注意的是,为了防止恶意的操作,模板方法上面都会加上final关键字

从西天取经的九九八十一难来看Java设计模式:模板方法模式的更多相关文章

  1. 歌乐第二弹:C++九九八十一

    第一弹传送门:极乐净土 二话不说,上代码(注意事项在第一弹里): #include <windows.h> //q前缀为低音,g为高音,s前缀为半音阶 const int q1 = 131 ...

  2. Tony老师带你来看Java设计模式:代理模式

    目录 定义 作用 意图 主要解决问题 优缺点 与装饰者模式的区别 结构 从Tony老师来看实现方式 静态代理 动态代理 JDK动态代理的实现 cglib动态代理的实现 定义 为其他对象提供一种代理来控 ...

  3. 从中国加入WTO来看Java设计模式:中介者模式

    目录 应用场景 中介者模式 定义 意图 主要解决问题 何时使用 优缺点 世界贸易组织WTO 应用场景 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象 想通过一个 ...

  4. 一起来看Java设计思想之23种设计模式

    目录 怎么使用设计模式 23种设计模式 创建型模式 结构型模式 行为型模式 总结 怎么使用设计模式 为什么要使用设计模式? 编写代码,写接口.写类.写方法 用设计模式做设计的作用是什么? 指导.规定如 ...

  5. 第三百八十一节,Django+Xadmin打造上线标准的在线教育平台—xadmin全局配置

    第三百八十一节,Django+Xadmin打造上线标准的在线教育平台—xadmin全局配置 1.xadmin主题设置 要使用xadmin主题,需要在一个app下的adminx.py后台注册文件里,写一 ...

  6. “全栈2019”Java第八十一章:外部类能否访问嵌套接口里的成员?

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  7. 孤荷凌寒自学python第八十一天学习爬取图片1

    孤荷凌寒自学python第八十一天学习爬取图片1 (完整学习过程屏幕记录视频地址在文末) 通过前面十天的学习,我已经基本了解了通过requests模块来与网站服务器进行交互的方法,也知道了Beauti ...

  8. 《手把手教你》系列基础篇(八十一)-java+ selenium自动化测试-框架设计基础-TestNG如何暂停执行一些case(详解教程)

    1.简介 在实际测试过程中,我们经常会遇到这样的情况,开发由于某些原因导致一些模块进度延后,而你的自动化测试脚本已经提前完成,这样就会有部分模块测试,有部分模块不能进行测试.这就需要我们暂时不让一些t ...

  9. Java设计模式(十一) 享元模式

    原创文章,同步发自作者个人博客 http://www.jasongj.com/design_pattern/flyweight/.转载请注明出处 享元模式介绍 享元模式适用场景 面向对象技术可以很好的 ...

随机推荐

  1. docker镜像常用操作的基本命令

    1.拉取/下载镜像 docker pull 镜像名称       (可以从网易云镜像中心获取要下载的镜像) 2.查看已经下载的镜像 docker images 3.删除本地镜像 docker rmi ...

  2. idea分布式创建子模块后不能创建java文件

    问题描述:多模块情况下,创建java文件,找不到java类,如下图,即使手动创建,在里面编写内容也没有任何反应. 解决方案:右键将文件标记为Sources Root便可以了,如果想要标记为资源文件的话 ...

  3. matlab load函数用法 实例

    一 语法: load(filename) load(filename,variables) load(filename,'-ascii') load(filename,'-mat') load(fil ...

  4. s2010 安装mvc3

    下载链接如下:MVC 3安装包:http://www.microsoft.com/downloads/zh-cn/details.aspx?familyid=d2928bc1-f48c-4e95-a0 ...

  5. Pyqt5——带图标的表格(Model/View)

    需求:表格中第一列内容为学生学号,为了突出学号的表示,在第一列的学号旁增加学号图标. 实现:(1)使用Qt的model-view模式生成表格视图. (2)重写代理(QAbstractItemDeleg ...

  6. 《C++ Primer》笔记 第11章 关联容器

    关联容器类型 解释 按关键字有序保存元素 -- map 关联数组:保存关键字-值对 set 关键字即值,即只保存关键字的容器 multimap 关键字可重复出现的map multiset 关键字可重复 ...

  7. Fedora/Centos使用dnf/yum为Firefox安装Flash,两行命令超简单

    Fedora/Centos使用dnf/yum为Firefox安装Flash,两行命令超简单 Flash已死,我想这个方法应该已经失效了吧,毕竟是从adobe的官方下载的,应该是撤链接了,我也很久没安装 ...

  8. Spring 的 IOC

    1. 什么是IOC IOC的好处 IOC的思想是将需要的对象通过外部传入进来,而不是自己创建.这样的设计方式更加灵活.在Spring中对象之间的依赖关系也是由IOC容器来维护(类与类之间的依赖关系,使 ...

  9. web实现时钟效果

    纯原生开发时钟效果,话不多说直接上代码. HTML标签部分 <div class="cricles">         <div class="poin ...

  10. 前端学习 node 快速入门 系列 —— 服务端渲染

    其他章节请看: 前端学习 node 快速入门 系列 服务端渲染 在简易版 Apache一文中,我们用 node 做了一个简单的服务器,能提供静态资源访问的能力. 对于真正的网站,页面中的数据应该来自服 ...