模板方法模式——看看 JDK 和 Spring 是如何优雅复用代码的

模板方法模式是一种行为设计模式,用于在超类中定义算法框架,允许子类重写具体步骤。文章通过饮品制作的示例介绍了模板方法模式,展示了其在JDK(如Comparable接口)和Spring(如ApplicationContext初始化)中的应用,强调了其封装不变部分、扩展可变部分的优势以及在代码复用和维护中的价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不管是我们学习并发编程中的 AQS,还是看 Spring 的源码,肯定都会遇到模板方法模式,它简直太常见了。

前言

模板,顾名思义,它是一个固定化、标准化的东西。

模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。

场景问题

程序员不愿多扯,上来先干两行代码

网上模板方法的场景示例特别多,个人感觉还是《Head First 设计模式》中的例子比较好。

假设我们是一家饮品店的师傅,起码需要以下两个手艺

真简单哈,这么看,步骤大同小异,我的第一反应就是写个业务接口,不同的饮品实现其中的方法就行,像这样

画完类图,猛地发现,第一步和第三步没什么差别,而且做饮品是个流程式的工作,我希望使用时,直接调用一个方法,就去执行对应的制作步骤。

灵机一动,不用接口了,用一个抽象父类,把步骤方法放在一个大的流程方法 makingDrinks() 中,且第一步和第三步,完全一样,没必要在子类实现,改进如下

再看下我们的设计,感觉还不错,现在用同一个 makingDrinks() 方法来处理咖啡和茶的制作,而且我们不希望子类覆盖这个方法,所以可以申明为 final,不同的制作步骤,我们希望子类来提供,必须在父类申明为抽象方法,而第一步和第三步我们不希望子类重写,所以我们声明为非抽象方法

public abstract class Drinks {

    void boilWater() {
        System.out.println("将水煮沸");
    }

    abstract void brew();

    void pourInCup() {
        System.out.println("倒入杯子");
    }

    abstract void addCondiments();
    
    public final void makingDrinks() {
        //热水
        boilWater();
        //冲泡
        brew();
        //倒进杯子
        pourInCup();
        //加料
        addCondiments();
    }
}

接着,我们分别处理咖啡和茶,这两个类只需要继承父类,重写其中的抽象方法即可(实现各自的冲泡和添加调料)

public class Tea extends Drinks {
    @Override
    void brew() {
        System.out.println("冲茶叶");
    }
    @Override
    void addCo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值