模板模式(TemplateMethod)
什么是Template Method模式
在父类中定义处理流程的框架,在子类中实现具体处理的模式就称为Template Mehtod模式。模板模式的关键是:子类可以置换掉父类的可变部分,但是子类却不可以改变模板方法所代表的顶级逻辑。
类图:
Template Method角色
抽象模板(Abstract Template)角色有如下责任:
- 定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。
- 定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。
具体模板(Concrete Template)角色又如下责任:
- 实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。
- 每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。
示例:
抽象模板角色类,abstractMethod()、hookMethod()等基本方法是顶级逻辑的组成步骤,这个顶级逻辑由templateMethod()方法代表。
public abstract class AbstractTemplate {
/**
* 模板方法:
* 1.一个模板方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。
* 2.一个抽象类可以有任意多个模板方法,而不限于一个。每一个模板方法都可以调用任意多个具体方法。
*/
public void templateMethod(){
//调用基本方法
abstractMethod();
hookMethod();
concreteMethod();
}
/**
* 基本方法的声明(由子类实现)
*/
protected abstract void abstractMethod();
/**
* 基本方法(钩子方法)一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空实现,作为方法的默认实现。
* 钩子方法的名字应当以do开始,这是熟悉设计模式的Java开发人员的标准做法。在上面的例子中,钩子方法hookMethod()应当以do开头;在HttpServlet类中,也遵从这一命名规则,如doGet()、doPost()等方法
*/
protected void hookMethod(){}
/**
* 基本方法(具体方法)一个具体方法由抽象类声明并实现,而子类并不实现或置换。
*/
private final void concreteMethod(){
//业务相关的代码
}
}
具体模板角色类,实现了父类所声明的基本方法,abstractMethod()方法所代表的就是强制子类实现的剩余逻辑,而hookMethod()方法是可选择实现的逻辑,不是必须实现的。
public class ConcreteTemplate extends AbstractTemplate{
//基本方法的实现
@Override
public void abstractMethod() {
//业务相关的代码
}
//重写父类的方法
@Override
public void hookMethod() {
//业务相关的代码
}
}
使用场景:
考虑一个计算存款利息的例子。假设系统需要支持两种存款账号,即货币市场(Money Market)账号和定期存款(Certificate of Deposite)账号。这两种账号的存款利息是不同的,因此,在计算一个存户的存款利息额时,必须区分两种不同的账号类型。
这个系统的总行为应当是计算出利息,这也就决定了作为一个模板方法模式的顶级逻辑应当是利息计算。由于利息计算涉及到两个步骤:一个基本方法给出账号种类,另一个基本方法给出利息百分比。这两个基本方法构成具体逻辑,因为账号的类型不同,所以具体逻辑会有所不
同。显然,系统需要一个抽象角色给出顶级行为的实现,而将两个作为细节步骤的基本方法留给具体子类实现。由于需要考虑的账号有两种:一是货币市场账号,二是定期存款账号。系统的类结构如下图所示。
抽象模板角色:
package org.burning.sport.design.pattern.templatemethod; public abstract class Account { /**
* 模板方法,计算利息数额
* @return 返回利息数额
*/
public final double calculateInterest() {
double interestRate = doCalculateInterestRate();
String accountType = doCalculateAccountType();
double amount = calculateAmount(accountType);
return amount * interestRate;
} /**
* 基本方法留给子类实现
*/
protected abstract String doCalculateAccountType(); /**
* 基本方法留给子类实现
*/
protected abstract double doCalculateInterestRate(); /**
* 具体方法
* @param accountType
*/
private double calculateAmount(String accountType){
if("Money Market".equals(accountType)) {
return 8000.00;
} else {
return 7243.00;
}
} }
具体模板角色:
package org.burning.sport.design.pattern.templatemethod; /**
* 具体模板角色类
*/
public class MoneyMarketAccount extends Account{
@Override
protected String doCalculateAccountType() {
return "Money Market";
} @Override
protected double doCalculateInterestRate() {
return 0.045;
}
}
package org.burning.sport.design.pattern.templatemethod; /**
* 具体模板角色类
*/
public class CDAccount extends Account {
@Override
protected String doCalculateAccountType() {
return "Certificate of Deposite";
} @Override
protected double doCalculateInterestRate() {
return 0.06;
}
}
客户端Client:
package org.burning.sport.design.pattern.templatemethod; public class ClientMain {
public static void main(String[] args) {
Account account = new MoneyMarketAccount();
System.out.println("货币市场账号的利息数额为:" + account.calculateInterest()); account = new CDAccount();
System.out.println("定期账号的利息数额为:" + account.calculateInterest()); }
}
参考:
[1] 博客,https://www.cnblogs.com/java-my-life/archive/2012/05/14/2495235.html
[2] 《图解设计模式》,人民邮电出版社,结城浩
模板模式(TemplateMethod)的更多相关文章
- 设计模式学习-使用go实现模板模式
模板模式 定义 模板模式的作用 优点 缺点 适用范围 代码实现 回调 模板模式 VS 回调 参考 模板模式 定义 模板模式(TemplateMethod):定义一个操作中的算法骨架,而将一些步骤延迟到 ...
- 模板模式(C++) 【转】
模板模式(template)在面向对象系统的设计和开发过程中,一定会有这样的情况:对于一些功能,在不同的对象身上展示不同的作用,但是功能的框架是一样的,这就是模板(template)模式的用武之地,我 ...
- Head First 设计模式系列之一----模板模式(java版)
开篇序言:四人帮的设计模式对于我这个菜鸟看着打瞌睡,后面果断买了一本head first的,感觉还可以像看报纸似的,花了一个寒假的晚上看了大半,确实内容也挺吸引人的,讲的很风趣.否则我也不可能,大过年 ...
- 学习笔记——模板模式Template
模板模式,主要是利用多态来实现具体算法和父类逻辑的松耦合.父类中TemplateMethod内部定义了相应的算法操作顺序,子类负责实现相应的具体实现. 举例: 项目中曾遇到过一个需求,叫做高级价格体系 ...
- 大话设计模式之模板模式 C#
学无止境,精益求精 十年河东,十年河西,莫欺少年穷 今天一起探讨模板模式,如下: 一.概念 上一篇文章讲了大话设计模式:原型模式,原型模式主要是通过Clone()方法<深浅复制>,创建新的 ...
- 设计模式——模板模式(Template Pattern)
在读Spring源码的时候,发现Spring代码中运用了大量的模板模式,比如根据文件系统目录加载配置文件(FileSystemXmlApplicationContext),类路径加载配置文件(Clas ...
- php设计模式——模板模式
最近打算巩固,整理一下设计模式相关的内容.这篇是关于 ——模板模式! 原文:http://www.jb51.net/article/76052.htm ----------------------- ...
- Thread之模板模式
我们知道,在实际使用线程的时候,真正的执行逻辑都是写在run方法里面,run方法是线程的执行单元,如果我们直接使用Thread类实现多线程,那么run方法本身就是一个空的实现,如下: /** * If ...
- 模板模式(Template Pattern)
模板模式(Template Pattern) -- 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. ...
随机推荐
- VS2010程序打包操作--超详细
1. 在vs2010 选择“新建项目”----“其他项目类型”----“Visual Studio Installerà“安装项目”: 命名为:Setup1 . 这是在VS2010中将有三个文件夹, ...
- _RecordsetPtr使用方法
_variant_t vUsername,vID,vname; //变量声明 _RecordsetPtr m_pRecordset; //记录集 CString strid; _Connect ...
- 转:解决windows下eclipse中android项目关联android library project失败问题
近日,在做一个人人的第三方小项目.打算直接使用renren 的sdk 进行开发.因为renren的sdk是以android library project 形式发布的(关于这种project的内容可以 ...
- hdu 5035 指数分布无后效性
http://acm.hdu.edu.cn/showproblem.php?pid=5035 n个柜台每个柜台服务的时间都满足指数分布t=p(k),求min(p(k)+t)的期望 指数分布一个有趣的特 ...
- hdu 5045 N个人做M道题的正确率
http://acm.hdu.edu.cn/showproblem.php?pid=5045 给出N个人做M道题的正确率,每道题只能由一个人做出,并且当所有人都做出来且仅做出一道题时,做过题的人才可以 ...
- [leetcode] 16. Add Binary
这个题目相对有点奇怪,题目如下: Given two binary strings, return their sum (also a binary string). For example, a = ...
- 使用 Project Siena 生成一个 Windows Store 应用
继 App Studio 之后微软又一力作 Project Siena [Win8 应用神器]给初学开发 或 对 Windows Store 应用感兴趣的同学们的一个福利,可以通过 一个简单的应用可以 ...
- c++日志输出库 spdlog 简介(3)多线程控制台输出日志
spdlog源码分析:https://www.cnblogs.com/eskylin/p/6483199.html spdlog的异步模式使得spdLog可以支持多线程,于是写了一个多线程的小例子: ...
- netcore配置文件与发布
这段时间好几次想写博客,但是却发现无法编辑,至今都不行 CuteEditor TinyMCE(推荐) 以上两种都不行,只好更改默认编辑器为textbox. 一直以为被封了还是怎么滴,原来是突然不支持c ...
- C#多线程编程系列(五)- 使用任务并行库
目录 1.1 简介 1.2 创建任务 1.3 使用任务执行基本的操作 1.4 组合任务 1.5 将APM模式转换为任务 1.6 将EAP模式转换为任务 1.7 实现取消选项 1.8 处理任务中的异常 ...