在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。

例如,去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业务、对银行工作人员进行评分等,其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人而异,它可能是存款、取款或者转账等,可以延迟到子类中实现。

1. 定义与特点

定义:
一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。

优点:

  • 它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
  • 它在父类中提取了公共的部分代码,便于代码复用。
  • 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。

缺点:

  • 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,间接地增加了系统实现的复杂度。
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
  • 由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍。

2. 应用场景

模板方法模式通常适用于以下场景。

  • 算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
  • 当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。首先,要识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
  • 当需要控制子类的扩展时,模板方法只在特定点调用钩子操作,这样就只允许在这些点进行扩展。

3. 结构与实现

模板方法模式需要注意抽象类与具体子类之间的协作。它用到了虚函数的多态性技术以及“不用调用我,让我来调用你”的反向控制技术。现在来介绍它们的基本结构。

结构
模板方法模式包含以下主要角色。
1)抽象类/抽象模板(Abstract Class)
抽象模板类,负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下。

① 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。

② 基本方法:是整个算法中的一个步骤,包含以下几种类型。

  • 抽象方法:在抽象类中声明,由具体子类实现。
  • 具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。
  • 钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。

2)具体子类/具体实现(Concrete Class)
具体实现类,实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤。

实现
实现代码:

public class TemplateMethodPattern {public static void main(String[] args) {AbstractClass tm = new ConcreteClass();tm.TemplateMethod();}
}
//抽象类
abstract class AbstractClass {//模板方法public void TemplateMethod() {SpecificMethod();abstractMethod1();abstractMethod2();}//具体方法public void SpecificMethod() {System.out.println("抽象类中的具体方法被调用...");}//抽象方法1public abstract void abstractMethod1();//抽象方法2public abstract void abstractMethod2();
}
//具体子类
class ConcreteClass extends AbstractClass {public void abstractMethod1() {System.out.println("抽象方法1的实现被调用...");}public void abstractMethod2() {System.out.println("抽象方法2的实现被调用...");}
}

运行结果:

抽象类中的具体方法被调用...
抽象方法1的实现被调用...
抽象方法2的实现被调用...

4. 实例

【例1】用模板方法模式实现出国留学手续设计程序。
分析:出国留学手续一般经过以下流程:索取学校资料,提出入学申请,办理因私出国护照、出境卡和公证,申请签证,体检、订机票、准备行装,抵达目标学校等,其中有些业务对各个学校是一样的,但有些业务因学校不同而不同,所以比较适合用模板方法模式来实现。

程序代码如下:

public class StudyAbroadProcess {public static void main(String[] args) {StudyAbroad tm = new StudyInAmerica();tm.TemplateMethod();}
}
//抽象类: 出国留学
abstract class StudyAbroad {public void TemplateMethod() //模板方法{LookingForSchool(); //索取学校资料ApplyForEnrol();    //入学申请ApplyForPassport(); //办理因私出国护照、出境卡和公证ApplyForVisa();     //申请签证ReadyGoAbroad();    //体检、订机票、准备行装Arriving();         //抵达}public void ApplyForPassport() {System.out.println("三.办理因私出国护照、出境卡和公证:");System.out.println("  1)持录取通知书、本人户口簿或身份证向户口所在地公安机关申请办理因私出国护照和出境卡。");System.out.println("  2)办理出生公证书,学历、学位和成绩公证,经历证书,亲属关系公证,经济担保公证。");}public void ApplyForVisa() {System.out.println("四.申请签证:");System.out.println("  1)准备申请国外境签证所需的各种资料,包括个人学历、成绩单、工作经历的证明;个人及家庭收入、资金和财产证明;家庭成员的关系证明等;");System.out.println("  2)向拟留学国家驻华使(领)馆申请入境签证。申请时需按要求填写有关表格,递交必需的证明材料,缴纳签证。有的国家(比如美国、英国、加拿大等)在申请签证时会要求申请人前往使(领)馆进行面试。");}public void ReadyGoAbroad() {System.out.println("五.体检、订机票、准备行装:");System.out.println("  1)进行身体检查、免疫检查和接种传染病疫苗;");System.out.println("  2)确定机票时间、航班和转机地点。");}public abstract void LookingForSchool();//索取学校资料public abstract void ApplyForEnrol();   //入学申请public abstract void Arriving();        //抵达
}
//具体子类: 美国留学
class StudyInAmerica extends StudyAbroad {@Overridepublic void LookingForSchool() {System.out.println("一.索取学校以下资料:");System.out.println("  1)对留学意向国家的政治、经济、文化背景和教育体制、学术水平进行较为全面的了解;");System.out.println("  2)全面了解和掌握国外学校的情况,包括历史、学费、学制、专业、师资配备、教学设施、学术地位、学生人数等;");System.out.println("  3)了解该学校的住宿、交通、医疗保险情况如何;");System.out.println("  4)该学校在中国是否有授权代理招生的留学中介公司?");System.out.println("  5)掌握留学签证情况;");System.out.println("  6)该国政府是否允许留学生合法打工?");System.out.println("  8)毕业之后可否移民?");System.out.println("  9)文凭是否受到我国认可?");}@Overridepublic void ApplyForEnrol() {System.out.println("二.入学申请:");System.out.println("  1)填写报名表;");System.out.println("  2)将报名表、个人学历证明、最近的学习成绩单、推荐信、个人简历、托福或雅思语言考试成绩单等资料寄往所申请的学校;");System.out.println("  3)为了给签证办理留有充裕的时间,建议越早申请越好,一般提前1年就比较从容。");}@Overridepublic void Arriving() {System.out.println("六.抵达目标学校:");System.out.println("  1)安排住宿;");System.out.println("  2)了解校园及周边环境。");}
}

运行结果如下:

一.索取学校以下资料:1)对留学意向国家的政治、经济、文化背景和教育体制、学术水平进行较为全面的了解;2)全面了解和掌握国外学校的情况,包括历史、学费、学制、专业、师资配备、教学设施、学术地位、学生人数等;3)了解该学校的住宿、交通、医疗保险情况如何;4)该学校在中国是否有授权代理招生的留学中介公司?5)掌握留学签证情况;6)该国政府是否允许留学生合法打工?8)毕业之后可否移民?9)文凭是否受到我国认可?
二.入学申请:1)填写报名表;2)将报名表、个人学历证明、最近的学习成绩单、推荐信、个人简历、托福或雅思语言考试成绩单等资料寄往所申请的学校;3)为了给签证办理留有充裕的时间,建议越早申请越好,一般提前1年就比较从容。
三.办理因私出国护照、出境卡和公证:1)持录取通知书、本人户口簿或身份证向户口所在地公安机关申请办理因私出国护照和出境卡。2)办理出生公证书,学历、学位和成绩公证,经历证书,亲属关系公证,经济担保公证。
四.申请签证:1)准备申请国外境签证所需的各种资料,包括个人学历、成绩单、工作经历的证明;个人及家庭收入、资金和财产证明;家庭成员的关系证明等;2)向拟留学国家驻华使(领)馆申请入境签证。申请时需按要求填写有关表格,递交必需的证明材料,缴纳签证。有的国家(比如美国、英国、加拿大等)在申请签证时会要求申请人前往使(领)馆进行面试。
五.体检、订机票、准备行装:1)进行身体检查、免疫检查和接种传染病疫苗;2)确定机票时间、航班和转机地点。
六.抵达目标学校:1)安排住宿;2)了解校园及周边环境。

【Java -- 设计模式】模板方法模式(Template Method)相关推荐

  1. 趣谈设计模式 | 模板方法模式(Template Method):封装不变部分,扩展可变部分

    文章目录 案例:房屋建造 模板方法模式 模板方法模式与策略模式 总结 完整代码与文档 这个设计模式过于简单,所以不是很好举例- 案例:房屋建造 假设我们是建筑公司中的规划者,负责设定建筑方案,在初期我 ...

  2. JAVA设计模式(14) —行为型模板方法模式(Template Method)

    1 定义: 模板方法模式(Template Method) Define the skeleton of an algorithm in anoperation, deferring some ste ...

  3. java 模板方法_设计模式(java实现)_模板方法模式(Template method)

    设计模式(java实现)_模板方法模式(Template method) 模板方法模式是编程中经常用到到的模式.它定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现.这样,新的子类可以在不改变一个 ...

  4. 模板方法模式 Template method 行为型 设计模式(二十六)

    模板方法模式 Template method 上图为网上百度的一份简历模板截图 相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为你的 ...

  5. JAVA 设计模式 模板方法模式

    定义 模板方法模式 (Template Method) 定义了一个操作中的算法的骨架,而将部分步骤的实现在子类中完成. 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 模 ...

  6. Java设计模式-模板方法模式详解

    Java设计模式-模板方法模式 文章目录 Java设计模式-模板方法模式 0.前言 1.模板方法原理 2.模板方法模式中的角色 3.模板方法模式的UML类图 4.代码实现 5.编码测试 6.模板模式中 ...

  7. Java设计模式 - 模板方法模式

    Java设计模式 - 模板方法模式 定义一个算法的骨架,并将一些步骤通过子类表达. UML图示 要点 1. 定义一个算法的骨架 - 建立一个抽象类 2. 将一些步骤通过子类表达 - 子类继承抽象类 赋 ...

  8. 设计模式之模板方法模式(Template Method Pattern)

    模式的定义与特点 模板方法(Template Method)模式的定义如下:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤.它 ...

  9. C++设计模式——模板方法(Template Method)

    模板方法(template method)设计模式用于定义一个包含许多步骤的算法框架,允许子类重写(覆盖)算法的某一个步骤而不改变算法整体的流程和框架. 模板方法提供的流程是骨架,子类无须覆盖模板方法 ...

  10. Java设计模式——模板方法模式【Template Method Pattern】

    一.引言 23种设计模式大概分为三大类: 5种(创建型模式):工厂方法模式.抽象工厂模式.单例模式.原型模式.建造者模式. 7种(结构型模式):适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组 ...

最新文章

  1. Python Qt GUI设计:窗口布局管理方法【强化】(基础篇—6)
  2. xampp中php连接mysql数据库乱码解决
  3. 揭秘《英雄联盟》客户端更新运行自动化测试
  4. 关于mysql数据库的外键插入报错:Cannot add or update a child row: a foreign key constraint fails,完整性问题
  5. 10恢复出厂设置_Mac系统如何恢复出厂设置
  6. linux系统sudoers文件夹权限777以及/etc/profile文件修改后无法进入系统问题
  7. Ubuntu20.04安装eBPF BCC
  8. DOM 中的事件处理
  9. 干支纪年法简便算法_基于回弹法的混凝土实体质量过程控制研究
  10. 安卓按键:紫猫老师的正则教程
  11. 计算机大纲级别怎么设置,word 怎样修改大纲级别的字体?
  12. python语法错误检查_如何检查python的语法正确性
  13. 蓝筹股是什么意思?低估值蓝筹股有哪些?拥有蓝筹股的好处?
  14. 钉钉导航栏分享按钮的显示/隐藏
  15. 一年中的最后一天说说_2018最后一天感言说说 怎么发朋友圈告别2018年
  16. php 美团配送 生成签名
  17. 2022年项目经理的发展方向-上课解读及心得
  18. 浴火重生,燃起奋斗的欲望
  19. SuSE and NLD9 user pls note
  20. HTML(1) 实现一个简单的课程表

热门文章

  1. 物联网定位技术超全解析
  2. 图书管理系统/库存管理系统等计算机毕业论文设计
  3. ITIL 4讲解:ITIL4的设计框架解析
  4. coin3d核心类整理
  5. 深度linux如何打开exe文件,在深度系统中直接运行exe文件的方法
  6. 网络学习(学堂在线)
  7. matlab教程分析,MATLAB数据分析教程
  8. Ubuntu安装搜狗拼音输入法(中文输入法)
  9. opengl编程指南第9版源码编译注意事项
  10. php滑动门效果,js实现简洁的TAB滑动门效果代码