设计模式系列:搞懂模板方法模式,先定框架,再补充细节

模板方法模式是一种行为设计模式,用于在抽象类中定义算法框架,将不变部分与可变部分分离。它允许子类在不修改算法结构的情况下重定义特定步骤。在银行业务场景中,模板方法模式可用于描述取号、排队、办理业务和评价的固定流程,而业务类型(如存款、转账)则由具体子类实现。这种模式提高了代码复用性和扩展性,但也可能导致类数量增加和维护复杂度上升。
摘要由CSDN通过智能技术生成

模板方法模式的定义:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。属于行为型模式。

模板方法模式的本质就是抽象封装流程、处理通用实现、具体子类可以对其中的一些流程节点进行重写不同的实现逻辑。

模板方法模式的结构:模板方法模式主要包含以下2个角色。

  1. 抽象模板(Abstract Class):抽象模板类,负责给出一个算法的轮廓和骨架。
  2. 具体实现(Concrete Class):具体实现类,对模板中的某些步骤节点进行重写。

在模板方法模式中,除了包含模板方法和每个步骤的方法外,还包含钩子方法。钩子方法的目的是干预执行流程,使用钩子方法可以控制某些步骤的执行,使流程更灵活。

模板方法模式的通用实现:

//抽象模板
public abstract class AbstractClass {
    //模板方法
    public final void TemplateMethod() {
        SpecificMethod();
        if(needMethod1()){
            abstractMethod1();
        }
        abstractMethod2();
    }
    //具体方法
    protected void SpecificMethod() {
        System.out.println("抽象类中的具体方法被调用...");
    }
    //抽象方法1
    protected abstract void abstractMethod1();
    //抽象方法2
    protected abstract void abstractMethod2();

    protected boolean needMethod1(){
        return true;
    }
}

//具体模板
public class ConcreteClass extends AbstractClass{
    private boolean needMethod1;

    public ConcreteClass(boolean needMethod1){
        this.needMethod1 = needMethod1;
    }

    @Override
    protected void abstractMethod1() {
        System.out.println("抽象方法1的实现被调用...");
    }

    @Override
    protected void abstractMethod2() {
        System.out.println("抽象方法2的实现被调用...");
    }

    @Override
    protected boolean needMethod1() {
        return needMethod1;
    }
}

//测试类
public class TemplateMethodTest {
    public static void main(String[] args) {
        AbstractClass tm = new ConcreteClass(false);
        tm.TemplateMethod();
    }
}

模板方法模式的结构图:

模板方法模式的应用实例:我们平时去银行办理业务一般要经过以下4个流程:取号、排队、办理业务、对工作人员进行评价,其中取号、排队和评价是固定的,可以在抽象类具体实现,每个人都一样,但是办理业务可能是存款、取款或者转账等等,可以延迟到子类中实现。如果前面没人就不需要排队,所以排队不是必须流程,可以使用钩子方法控制。

//抽象类
public abstract class AbstractBusiness {
    private int number;

    public final void doBusinessTemplate(){
        //取号
        getNumber();
        //前面有人就要排队
        if(havePerson()){
            lineUp();
        }
        //办业务
        doBusiness();
        //评价
        evaluate();
    }

    private void getNumber() {
        Random random = new Random();
        number = random.nextInt(5);
        if(number>1){
            System.out.println("你是"+number+"号,前面有"+(number-1)+"人!");
        }else{
            System.out.println("你是"+number+"号,请直接去办理业务!");
        }
    }

    private boolean havePerson() {
        if(number<2){
            return false;
        }
        return true;
    }

    private void lineUp(){
        System.out.println("前面有"+(number-1)+"人,请耐心等待!");
    }

    protected abstract void doBusiness();

    protected abstract void evaluate();
}

//转账
public class TransferAccounts extends AbstractBusiness{
    @Override
    protected void doBusiness() {
        System.out.println("我要转账!!!");
    }

    @Override
    protected void evaluate() {
        System.out.println("5星好评!!!");
    }
}

//存钱
public class SaveMoney extends AbstractBusiness{
    @Override
    protected void doBusiness() {
        System.out.println("我要存钱!!!");
    }

    @Override
    protected void evaluate() {
        System.out.println("4星好评!!!");
    }
}

//测试类
public class Test {
    public static void main(String[] args) {
        AbstractBusiness ta = new TransferAccounts();
        ta.doBusinessTemplate();

        AbstractBusiness sm = new SaveMoney();
        sm.doBusinessTemplate();
    }
}

上面实例的结构图:

模板方法模式的优点:

  1. 在抽象父类中提取了公共逻辑代码,提高代码的复用性。
  2. 通过子类扩展新的行为,提高代码的扩展性,符合开闭原则。

模板方法模式的缺点:

  1. 每个不同的实现都要定义一个子类,导致类的个数增加,设计也更加抽象,间接地增加了系统的复杂度。
  2. 由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍。

模板方法模式的应用场景:

  1. 算法的整体步骤很固定,但其中个别步骤易变时,可以使用模板方法模式,将易变部分抽象出来,供子类实现。
  2. 当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。
  3. 当需要控制子类的扩展时,模板方法只在特定点调用钩子方法,这样就只允许在这些点进行扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风雨编码路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值