2021年9月26日-设计模式值模板方法

第十四章:模板方法

一、基本介绍

现在我现在需要写一个程序来让机器人做奶茶,做奶茶的过程可以分为加奶粉、冲泡、加配料、包装几个过程。无论是做一杯什么口味的奶茶,它的步骤都是这几步,所以我就可以定义一个抽象类,做奶茶的各个步骤声明成抽象方法,不过大致的制作流程在这个抽象类中做实现

类图如下:

在这里插入图片描述

二、具体实现

MilkyTea 抽象类

public abstract class MilkyTea {
    // 方法的调用逻辑由父类决定
    void make() {
        addPowder();
        addWater();
        addCompound();
        encapsulation();
    }
    // 具体实现可能需要子类完成或覆盖
    abstract void addPowder();
    void addWater() {
        System.out.println("加入适量白开水");
    }
    abstract void addCompound();
    void encapsulation() {
        System.out.println("封装奶茶");
    }
}

VanillaMilkTea 子类

public class VanillaMilkTea extends MilkyTea {
    @Override
    void addPowder() {
        System.out.println("添加香草味奶粉");
    }

    @Override
    void addCompound() {
        System.out.println("添加椰果");
    }
}

RedBeanMilkTea 子类

public class RedBeanMilkTea extends MilkyTea {
    @Override
    void addPowder() {
        System.out.println("添加原为奶粉");
    }

    @Override
    void addCompound() {
        System.out.println("添加大量红豆");
    }
}

测试类

public class TemplateTest {
    public static void main(String[] args) {
        VanillaMilkTea vanillaMilkTea = new VanillaMilkTea();
        System.out.println("制作香草奶茶");
        vanillaMilkTea.make();
        System.out.println("============");
        System.out.println("制作红豆奶茶");
        RedBeanMilkTea redBeanMilkTea = new RedBeanMilkTea();
        vanillaMilkTea.make();
    }
}

钩子方法:我们在抽象父类中规定了方法的调用逻辑,但有时候某些方法并不一定需要执行,需要子类来决定。但是我们不太愿意让子类重写已经在父类中规定的调用逻辑,那怎么办?这时可以用一个钩子方法的返回值来决定方法的执行与否,子类通过重写钩子方法间接影响了调用的逻辑

改造后的 MilkyTea 父类

public abstract class MilkyTea {
    void make() {
        addPowder();
        addWater();
        // 让子类也有一定决定权
        if (isCompoundNeed())
            addCompound();
        encapsulation();
    }
    abstract void addPowder();
    void addWater() {
        System.out.println("加入适量白开水");
    }
    abstract void addCompound();
    void encapsulation() {
        System.out.println("封装奶茶");
    }

    boolean isCompoundNeed() {
        return true;
    }
}

VanillaMilkTea 不加香草

public class VanillaMilkTea extends MilkyTea {
    @Override
    void addPowder() {
        System.out.println("添加香草味奶粉");
    }

    @Override
    void addCompound() {
        System.out.println("添加椰果");
    }

    // 重写钩子方法,不加椰果
    @Override
    boolean isCompoundNeed() {
        return false;
    }
}

三、模板总结

1)算法(方法的调用逻辑)父类中做了实现,子类的作用就是对具体步骤做实现

2)一般模板方法都会加上 final 来防止子类的重写

3)一旦大的调用逻辑需要改变,只用改变父类一个类

4)子类可以通过不同的实现完成不同的功能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值