举个栗子

问题描述

小时候数学老师的随堂测验,都是在黑板上抄题目,然后再作答案。写一个抄题目的程序。

简单实现

学生甲抄的试卷

/*** 学生甲抄的试卷* Created by callmeDevil on 2019/7/14.*/
public class TestPaperA {// 试题1public void testQuestion1(){System.out.println("路飞在顶上战争之后,修炼了多久? a.3天 b.2年 c.2天 d.3年");System.out.println("答案:b");}// 试题2public void testQuestion2(){System.out.println("鸣人是第几代火影? a.六代 b.七代 c.八代 d.九代");System.out.println("答案:b");}}

学生乙抄的试卷

/*** 学生乙抄的试卷* Created by callmeDevil on 2019/7/14.*/
public class TestPaperB {// 试题1public void testQuestion1(){System.out.println("路飞在顶上战争之后,修炼了多久? a.3天 b.2年 c.2天 d.3年");System.out.println("答案:a");}// 试题2public void testQuestion2(){System.out.println("鸣人是第几代火影? a.六代 b.七代 c.八代 d.九代");System.out.println("答案:a");}}

测试

public class Test {public static void main(String[] args) {System.out.println("学生甲抄的试卷:");TestPaperA studentA = new TestPaperA();studentA.testQuestion1();studentA.testQuestion2();System.out.println("学生乙抄的试卷:");TestPaperB studentB = new TestPaperB();studentB.testQuestion1();studentB.testQuestion2();}}

测试结果

学生甲抄的试卷:
路飞在顶上战争之后,修炼了多久? a.3天 b.2年 c.2天 d.3年
答案:b
鸣人是第几代火影? a.六代 b.七代 c.八代 d.九代
答案:b
学生乙抄的试卷:
路飞在顶上战争之后,修炼了多久? a.3天 b.2年 c.2天 d.3年
答案:a
鸣人是第几代火影? a.六代 b.七代 c.八代 d.九代
答案:a

存在问题

两个学生抄试卷都非常类似,除了答案不同,没什么不一样,这样又容易错,又难以维护。因此老师出一份试卷,打印多份,让学生填写答案就可以了。应该把试题和答案分离,抽出一个父类,让两个子类继承它,公共的试题代码写到父类当中就行了。

提炼代码

试题父类

/*** 试题父类-动漫考题* Created by callmeDevil on 2019/7/14.*/
public class TestPaper {// 试题1public void testQuestion1(){System.out.println("路飞在顶上战争之后,修炼了多久? a.3天 b.2年 c.2天 d.3年");}// 试题2public void testQuestion2(){System.out.println("鸣人是第几代火影? a.六代 b.七代 c.八代 d.九代");}}

学生甲抄的试卷-版本2

/*** 学生甲抄的试卷-版本2* Created by callmeDevil on 2019/7/14.*/
public class TestPaperA2 extends TestPaper{@Overridepublic void testQuestion1() {super.testQuestion1();System.out.println("答案:b");}@Overridepublic void testQuestion2() {super.testQuestion2();System.out.println("答案:b");}
}

学生乙抄的试卷-版本2

/*** 学生乙抄的试卷-版本2* Created by callmeDevil on 2019/7/14.*/
public class TestPaperB2 extends TestPaper{@Overridepublic void testQuestion1(){super.testQuestion1();System.out.println("答案:a");}@Overridepublic void testQuestion2(){super.testQuestion2();System.out.println("答案:a");}}

客户端测试代码与测试结果此处省略,同上述简单实现。

存在的问题

  • 既然用了继承,并且肯定这个继承有意义,就应该要成为子类的模板,所有重复的代码都应该要上升到父类去,而不是让每个子类都去重复
  • 当我们要完成在某一个细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理
  • 在上面提炼的代码中,每个学生只是输出的答案不同,其他全部都是一样的,应该在此处改成一个虚方法,让每个子类去重写即可

模板方法模式

定义

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

UML图

代码实现

模板方法父类-动漫考题

/*** 模板方法父类-动漫考题* Created by callmeDevil on 2019/7/14.*/
public abstract class TestPaper {// 试题1public void testQuestion1(){System.out.println("路飞在顶上战争之后,修炼了多久? a.3天 b.2年 c.2天 d.3年");System.out.println("答案:" + answer1());//改成一个虚方法,下同}// 试题2public void testQuestion2(){System.out.println("鸣人是第几代火影? a.六代 b.七代 c.八代 d.九代");System.out.println("答案:" + answer2());}// 此方法的目的就是给继承的子类重写,因为这里每个人的答案都是不同的public abstract String answer1();public abstract String answer2();}

学生甲抄的试卷-模板方法实现

/*** 学生甲抄的试卷-模板方法实现* Created by callmeDevil on 2019/7/14.*/
public class TestPaperA3 extends TestPaper{@Overridepublic String answer1() {return "b";}@Overridepublic String answer2() {return "b";}}

学生乙抄的试卷-模板方法实现

/*** 学生乙抄的试卷-模板方法实现* Created by callmeDevil on 2019/7/14.*/
public class TestPaperB3 extends TestPaper{@Overridepublic String answer1() {return "a";}@Overridepublic String answer2() {return "a";}}

模板方法测试

/*** 模板方法测试* Created by callmeDevil on 2019/7/14.*/
public class Test3 {public static void main(String[] args) {System.out.println("学生甲抄的试卷:");// 将子类变量的声明改成父类,利用多态性实现了代码的复用TestPaper studentA = new TestPaperA3();studentA.testQuestion1();studentA.testQuestion2();System.out.println("学生乙抄的试卷:");TestPaper studentB = new TestPaperB3();studentB.testQuestion1();studentB.testQuestion2();}}

测试结果是一致的,此处不再贴出。

总结

  • 模板方法模式是通过把不变的行为搬移到父类,去除子类中重复的代码来体现它的优势
  • 模板方法模式就是提供了一个很好的代码复用平台
  • 当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。

大话设计模式笔记(八)の模板方法模式相关推荐

  1. 设计模式学习(八) 模板方法模式

    引入 定义:在一个方法中定义了一个算法的骨架,而将一些一些步骤延迟到子类中.模板方法使得子类可以在不改变算法接口的情况下,重新定义算法中的某些步骤. uml类图 这个模式是用来创建一个算法的模板,什么 ...

  2. 大话设计模式笔记 享元模式

    享元模式(Flyweigh),运用共享技术有效地支持大量细粒度的对象. package flyweight;//可以接受并作用于外部状态 public abstract class Flyweight ...

  3. 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...

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

    <Head First 设计模式>之模板方法模式--冲泡咖啡和茶 模板方法模式(Template) 在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变 ...

  5. 设计模式笔记八:过滤器模式

    原文:http://www.runoob.com/design-pattern/ 少许个人理解,如有错误请指出.欢迎一起讨论.(本文基本摘抄) 定义: 过滤器模式(Filter Pattern)或标准 ...

  6. 设计模式之04模板方法模式(笔记)

    1 定义: 1.1 定义: Define the skeleton of an algorithm in anoperation, deferring some steps to subclasses ...

  7. Java设计模式系列之——模板方法模式

    大事件 关注篮球或者喜欢逛社交网站的朋友们可能都知道,2019年10月5日,NBA休斯顿火箭队总经理莫雷在推特上发布了一张无知的涉港图片,引发全体中国人民的强烈抗议和不满,一时间舆论哗然,此后,NBA ...

  8. 23种设计模式之:模板方法模式

    转载地址:https://blog.csdn.net/zhengzhb/article/details/7405608 整理的设计模式实例:https://github.com/jinchuanchu ...

  9. 设计模式系列之 模板方法模式

    定义 在模板方法中定义一个算法的骨架,而将部分步骤延迟到子类中,使子类在不改变算法结构的情况下,重新定义算法中的部分步骤. 理解该模式的关键就在"模板"二字.什么是模板?模板就是预 ...

最新文章

  1. python002 一 eg: Python 入门技巧__环境搭建__git使用、git本地操作、 自建gitlab服务器
  2. Codeforces - 914F bitset 维护字符串匹配个数
  3. php mongodb 连接失败,解决PHP使用普通账号连接mongodb报错问题
  4. USACO / Factorials (简单模拟)
  5. go init函数_面试录 Go语言篇 内存模型
  6. html跳动爱心代码,html+css实现跳动爱心❥(^_-)-Go语言中文社区
  7. 如何编写有效的Bug Report
  8. 随机数-random模块
  9. 【一天一个C++小知识】008.内联函数
  10. JAVA日常优化---Guava缓存玩耍异步刷新
  11. bmfont-instructions
  12. PostSQL | Debug记录
  13. 使用vue+HBulider云游戏接口开发单击斗地主网页版
  14. m3u8 视频下载 ——M3U8 GETTER 批量下载版 使用说明
  15. 【Mockplus教程】账号和购买
  16. 软件工程阶段性总结(二)——软件计划和需求分析
  17. 校园网多拨网速叠加思路
  18. (Pytorch) YOLOV4 : 训练自己的数据集【左侧有码】
  19. 微信和支付宝又更新了,这几个功能很赞
  20. 第九天javaSE基础(学生管理系统)

热门文章

  1. dofilter在java中_FilterChain doFilter中的java.lang.NullPointerException方法
  2. Tensorflow(2.0+) 对五类医学图像进行分类
  3. 学校人员定位管理系统
  4. rust edition python3_PyO3首页、文档和下载 - Python 解释器的 Rust 绑定
  5. 单级倒立摆从建模到仿真
  6. Springboot + Vue 登录功能实现
  7. 气传导耳机哪个品牌比较好?四款优秀气传导耳机推荐
  8. 用Python的Turtle画mopemope
  9. 使用thyme leaf模板CRUD时遇到的坑
  10. 流量卡激活看快递:京东为快递激活,EMS/顺丰为自主激活。