1、定义
定义了一个操作中的算法的框架,而将一些布骤延迟到子类中。是的子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
2、使用场景
- 多个子类有公共方法,并且逻辑基本相同
- 可以把重复的、复杂的、核心算法设计为模板方法,周边的相关的代码抽到父类中
3、UML类图
角色说明:
- 抽象模板(AbstractClass)角色:定义了一个或多个抽象操作,以便让子类实现。
- 具体模板(ConcreteClass)角色:实现了AbstractClass角色定义的抽象操作,每个不同的具体模板都有不同的实现方式。
4、示例
下面将用模板方法计算银行活期和定期账户的利息。计算利息需要确定账户类型和相应类型的利息,即将这个两个方法抽象到模板类Account,具体实现由其子类实现。
/**
* 抽象模板、抽象账户类
* @author xiaofeizhu
*
*/
public abstract class Account {
// 账户
private String accountNumber;
public Account() {
this.accountNumber = null;
}
public Account(String account) {
super();
this.accountNumber = account;
}
// 确认账户类型,具体子类实现
protected abstract String getAccountType();
// 确认利息,具体子类实现
protected abstract double getInterestRate();
public double calculateAmount(String accountType, String accountNumber) {
return 4567.00;
}
// 模板方法,计算账户利息
public double calculateInterest() {
String accountType = getAccountType();
double interestRate = getInterestRate();
double amount = calculateAmount(accountType, accountNumber);
return amount * interestRate;
}
}
/**
* 具体模板类,活期账户
* @author xiaofeizhu
*
*/
public class DemandAccount extends Account{
@Override
protected String getAccountType() {
// TODO Auto-generated method stub
return "活期";
}
@Override
protected double getInterestRate() {
// TODO Auto-generated method stub
return 0.005d;
}
}
/**
* 具体模板类,定期账户
* @author xiaofeizhu
*
*/
public class FixedAccount extends Account{
@Override
protected String getAccountType() {
// TODO Auto-generated method stub
return "一年定期";
}
@Override
protected double getInterestRate() {
// TODO Auto-generated method stub
return 0.032d;
}
}
public class Client {
public static void main(String[] args) {
Account account = new DemandAccount();
System.out.println("活期利息:" + account.calculateInterest());
account = new FixedAccount();
System.out.println("定期利息:" + account.calculateInterest());
}
}
输出结果如下:
活期利息:22.835
定期利息:146.144
5、说明
优点:
- 封装不变得部分,扩展可变的部分,
- 提取公共部分代码,便于维护。
- 行为由父类控制,子类实现。