模板方法:基于继承,内部有一部分功能是固定,一部分不固定,将不固定的抽象出来让子类实现。
示例场景:
用户去银行办理业务,通常要走这样的流程:准备证件-取号-办理业务,
其中前两个都是固定的,只有办理业务这个流程,用户可能办理取款、存款、办卡等业务,是变动的,
这种时候就可以用模板方法模式
示例代码:
package com.cc.templatemethod;
/**
* 银行类
* @author cc
* @date 2021-12-21 11:34
*/
public abstract class Bank {
// 为了不让子类覆写,使用final修饰
public final void dealService() {
prepareCertificate();
takeNumber();
business();
}
public void prepareCertificate() {
System.out.println("准备身份证等证件");
}
public void takeNumber() {
System.out.println("取号");
}
// 办理业务
public abstract void business();
}
package com.cc.templatemethod;
/**
* 具体的存款业务
* @author cc
* @date 2021-12-21 11:39
*/
public class DepositBusiness extends Bank {
@Override
public void business() {
System.out.println("办理存款业务");
}
}
package com.cc.templatemethod;
/**
* 具体的取款业务
* @author cc
* @date 2021-12-21 11:40
*/
public class WithdrawalBusiness extends Bank{
@Override
public void business() {
System.out.println("办理取款业务");
}
}
测试一下:
package com.cc.templatemethod;
public class Main {
public static void main(String[] args) {
{
Bank bank = new DepositBusiness();
bank.dealService();
}
System.out.println();
{
Bank bank = new WithdrawalBusiness();
bank.dealService();
}
}
}
结果:
准备身份证等证件
取号
办理存款业务
准备身份证等证件
取号
办理取款业务
模板方法的优缺点
优点:
- 封装了不变部分,拓展可变部分,便于子类拓展
- 从父类中提取公共部分的代码,便于代码复用
- 子类通过拓展的方式来增加相应的功能,符合开闭原则
缺点:
- 每个不同的实现都要定义一个子类,这会导致类个数的增加,系统更加庞大,间接地增加了系统实现的复杂度
- 继承的缺点,模板方法主要通过继承实现,如果父类增加了新的抽象方法,所有子类都要进行修改
- 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致了一种反向的控制结构,增加了代码阅读难度