Java设计模式之模板方法模式

146 阅读2分钟

模板方法:基于继承,内部有一部分功能是固定,一部分不固定,将不固定的抽象出来让子类实现。

示例场景:

用户去银行办理业务,通常要走这样的流程:准备证件-取号-办理业务,
其中前两个都是固定的,只有办理业务这个流程,用户可能办理取款、存款、办卡等业务,是变动的,
这种时候就可以用模板方法模式

示例代码:

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();
        }
    }
}

结果:

准备身份证等证件
取号
办理存款业务
​
准备身份证等证件
取号
办理取款业务

模板方法的优缺点

优点

  • 封装了不变部分,拓展可变部分,便于子类拓展
  • 从父类中提取公共部分的代码,便于代码复用
  • 子类通过拓展的方式来增加相应的功能,符合开闭原则

缺点

  • 每个不同的实现都要定义一个子类,这会导致类个数的增加,系统更加庞大,间接地增加了系统实现的复杂度
  • 继承的缺点,模板方法主要通过继承实现,如果父类增加了新的抽象方法,所有子类都要进行修改
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致了一种反向的控制结构,增加了代码阅读难度