一、概述
定义一个操作中算法的框架,而将一些步骤延迟到子类中,模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
举个例子,请客吃饭包含(点单-吃东西-买单),点单跟买单固定不变,吃东西可以吃面条也可以吃汉堡。此时,将点单跟买单的代码放在父类中,对于吃东西只进行声明,而不进行实现,将其具体实现放在不同的子类上。
二、结构与实现
- 结构
(1)AbstractClass:
定义了一系列的基本操作,可以是具体也可以是抽象的,每一个基本操作对应算法的一个步骤。抽象类中实现了一个模板方法的,定义算法的框架,它可以调用抽象类中的基本方法,子类实现的基本方法,或其他对象中的方法。
(2)ConcreteClass:
抽象类的子类,实现或覆盖抽象类中定义的基本操作。
- 实现
//抽象类
//模板方法
public void templateMethod(){
primitiveOperation1();
primitiveOperation2();
primitiveOperation3();
}
//基本方法--具体方法
public void primitiveOperation1(){
//实现代码
}
//基本方法--抽象方法
public void primitiveOperation1();
//基本方法--钩子方法
public void primitiveOperation1(){
//实现代码
}
//子类
public void primitiveOperation2(){
//实现代码
}
public void primitiveOperation2(){
//实现代码
}
三、应用案例
- 分析
Account充当抽象类角色,CurrentAcount充当活期具体账户类,SavingAccount充当定期具体账户类。
-
类图
-
实现
public class client {
public static void main(String[] args) {
Account account=new CurrentAccount();
account.handle("jack","111");
}
}
abstract class Account{
public boolean validate(String account,String password){
System.out.println("账户为:"+account);
System.out.println("密码为:"+password);
if(account.equals("jack") && password.equals("111")){
return true;
}else {
return false;
}
}
public abstract void calculateInterest();
public void display(){
System.out.println("利息显示!");
}
//模板方法
public void handle(String account,String password){
if(!validate(account,password)){
System.out.println("账户或密码错误!");
return;
}
calculateInterest();
display();
}
}
class CurrentAccount extends Account{
@Override
public void calculateInterest() {
System.out.println("按活期计算利率!");
}
}
class SavingAccount extends Account{
@Override
public void calculateInterest() {
System.out.println("按定期利率计算利息!");
}
}
四、总结
- 抽象方法中有基本方法和模板方法,模板方法是将基本方法进行一个顺序的排列,基本方法中,如基本方法是固定,则可将具体方法写在父类,而不固定的,父类只进行声明,子类再进行实现。
- 适用环境:子类中公共行为应被提取出来并集中到一个公共父类中以避免代码重复;需要实现子类对父类的反向控制;一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。