描述
- 知道主要流程,不知道某些流程的具体实现时,可以使用模板方法模式。
- 比如:计算社保(工资的百分比)。已知工资,但是各地的社保基数算法不大一样,可以把社保的算法定义成抽象,由具体的各地子类来提供。
- 总结:可以把不知道的算法,在父类中定义成抽象方法,具体的算法由子类来实现
角色
-
抽象类:声明一个抽象父类,定义类轮廓和骨架,不清楚的算法方法,定义成抽象,由子类来实现。可分为:
- 模板方法:定义了算法的实现顺序步骤。应该是final类型
- 基本方法:
- 抽象方法(暂时不知道如何实现的,由子类实现具体的算法)
- 具体方法(已知的,可以实现的算法)
- 钩子方法(子类的结果来决定,父类是否执行某些流程)
-
具体子类:继承抽象类,具体实现父类抽象方法。
实现
public class Test {
public static void main(String[] args) {
FuJianTax fujian = new FuJianTax();
fujian.algorithm();
}
}
// 模板类
abstract class AbstractTax {
// 数据库读取工资 具体方法
public Integer readSalary() {
return 8000;
}
// 计算税 模板方法
public void algorithm() {
Integer salary = readSalary();
if (limit() >= salary) {
System.out.println("不需要上交税");
} else {
double money = (salary - limit()) * base();
System.out.println("需上缴税:" + money + "元");
}
}
// 具体税基数 抽象方法
public abstract Double base();
// 税务起收界限 抽象方法
public abstract Integer limit();
}
// 具体子类
class FuJianTax extends AbstractTax {
@Override
public Double base() {
return 0.05;
}
@Override
public Integer limit() {
return 5000;
}
}
优点
- 重复代码在父类,提高代码复用性。
- 父类调用子类方法,实现反转控制,开闭原则。
缺点
- 每个不同的实现都需要一个子类,类数量较大。
- 子类的算法反向影响父类,代码阅读难度提高。
使用场景
- 整体骨架,实现步骤不变,但是其中某个算法不确切,或容易变化时,可以使用模板方法模式。
- 需通过子类的实现来控制父类是否执行某个流程,实现子类反向控制父类,可以使用模板方法模式。
JDK中的应用
- InputStream 的 read() 方法