现实生活中很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单、吃东西、买单等几个步骤,通常情况下这几个步骤的次序是点单->吃东西->买单。但是第二步吃东西里,到底是先吃汉堡还是先吃鸡肉卷,这个步骤是可变的。
定义
定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得一个子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
结构
AbstractClass(抽象类)
在抽象类中定义一系列基本操作,这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时在抽象类中实现了一个模板方法,用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。
ConcreteClass(具体子类)
它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。
实现
// 抽象类 - 账户类
public abstract class Account{
public boolean validate(String account, String password) {
System.out.println("账号:" + account);
System.out.println("密码:" + password);
if("123456".equals(account) && "123456".equals(account)) {
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();
}
}
// 具体子类 - 活期账户类
public class CurrentAccount extends Account{
@Override
public void calculateInterest() {
System.out.println("按照活期利率计算利息!");
}
}
// 具体子类 - 定期账户类
public class SavingAccount extends Account{
@Override
public void calculateInterest() {
System.out.println("按定期利率计算利息!");
}
}
优点
1、在父类中形式化定义一个算法,由子类来实现细节处理,在子类实现详细的处理算法时并不会改变算法中步骤的执行次序。
2、鼓励用户恰当的使用继承实现代码复用
缺点
如果父类中可变的基本方法太多,会导致累的个数增加,系统更加庞大,设计也更加抽象。