Skip to content

面试速答(先看这里)

**一句话结论:**模板方法模式是一种行为设计模式,他的主要作用就是复用代码。

60秒标准回答:

模板方法模式是一种行为设计模式,他的主要作用就是复用代码。在很多时候,我们的代码中可能会有一些公共的部分并且还有一些定制的部分,那么公共这部分就可以定义在一个父类中,然后将定制的部分实现在子类中。这样子类可以根据需要扩展或重写父类的方法,而不需要改变算法的结构

我们通常会把模板方法模式和策略模式一起使用,因为当我们使用策略模式的时候,会把具体的策略实现在策略服务里面,但是还剩下一些通用的逻辑,就可以通过模板方法模式进行复用

我们拿一个常见的优惠券作为示例,假设我们需要定义一个优惠券的申请服务

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**我们通常会把模板方法模式和策略模式一起使用,因为当我们使用策略模式的时候,会把具体的策略实现在策略服务里面,但是还剩下一些通用的逻辑,就可以通过模板方法模式进行复用。
  • **要点2:**我们拿一个常见的优惠券作为示例,假设我们需要定义一个优惠券的申请服务。
  • **要点3:**以上是一个抽象类,这个类中有一个具体的方法applyCoupon,其中定义了一个优惠券申请的具体实现,并且编排了多个其他的方法。
  • **要点4:**这就是一个典型的模板方法。
  • **要点5:**以上,就是两个具体的实现,分别继承Coupon抽象类,并且实现其中的部分方法就行了。

**记忆锚点:**applyCoupon → FixedAmountCoupon → PercentageCoupon → 我们通常会把模板方法 → 编排了多个其他的方法 → 是一个典型的模板方法

加分表达:

  • 我们通常会把模板方法模式和策略模式一起使用,因为当我们使用策略模式的时候,会把具体的策略实现在策略服务里面,但是还剩下一些通用的逻辑,就可以通过模板方法模式进行复用。

追问准备:

  • 围绕「applyCoupon」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「FixedAmountCoupon」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「PercentageCoupon」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

模板方法模式是一种行为设计模式,他的主要作用就是复用代码。在很多时候,我们的代码中可能会有一些公共的部分并且还有一些定制的部分,那么公共这部分就可以定义在一个父类中,然后将定制的部分实现在子类中。这样子类可以根据需要扩展或重写父类的方法,而不需要改变算法的结构。

我们通常会把模板方法模式和策略模式一起使用,因为当我们使用策略模式的时候,会把具体的策略实现在策略服务里面,但是还剩下一些通用的逻辑,就可以通过模板方法模式进行复用。

📄 ✅你在工作中是如何使用设计模式的?

打开文档:✅你在工作中是如何使用设计模式的?

扩展知识 ​

示例 ​

我们拿一个常见的优惠券作为示例,假设我们需要定义一个优惠券的申请服务。

java
abstract class Coupon {
    // 模板方法,定义优惠券的应用流程
    public final void applyCoupon() {
        if (isCouponValid()) {
            if (isEligibleForDiscount()) {
                applyDiscount();
            }
            displayConfirmation();
        } else {
            displayInvalidCouponMessage();
        }
    }

    // 具体方法,用于判断优惠券是否有效
    protected boolean isCouponValid() {
        // 具体的判断逻辑,子类可以重写该方法来实现特定的有效性判断
        return true;
    }

    // 具体方法,用于判断用户是否符合优惠券的折扣条件
    protected boolean isEligibleForDiscount() {
        // 具体的判断逻辑,子类可以重写该方法来实现特定的条件判断
        return true;
    }

    // 抽象方法,由子类实现具体的优惠券折扣逻辑
    protected abstract void applyDiscount();

    // 抽象方法,由子类实现具体的优惠券确认展示逻辑
    protected abstract void displayConfirmation();

    // 具体方法,用于展示无效优惠券的信息
    protected void displayInvalidCouponMessage() {
        System.out.println("无效优惠券!");
    }
}

以上是一个抽象类,这个类中有一个具体的方法applyCoupon,其中定义了一个优惠券申请的具体实现,并且编排了多个其他的方法。

这就是一个典型的模板方法。我们可以基于这个抽象类来定义具体的实现:

java
class PercentageCoupon extends Coupon {
    @Override
    protected void applyDiscount() {
        // 具体的百分比折扣逻辑
        System.out.println("应用百分比折扣优惠!");
    }

    @Override
    protected void displayConfirmation() {
        // 具体的百分比优惠券确认展示逻辑
        System.out.println("百分比折扣优惠确认!");
    }
}

class FixedAmountCoupon extends Coupon {
    @Override
    protected void applyDiscount() {
        // 具体的固定金额折扣逻辑
        System.out.println("应用固定金额优惠!");
    }

    @Override
    protected void displayConfirmation() {
        // 具体的固定金额优惠券确认展示逻辑
        System.out.println("固定金额优惠确认!");
    }
}

以上,就是两个具体的实现,分别继承Coupon抽象类,并且实现其中的部分方法就行了。

这样我们在实际使用时,就可以直接用FixedAmountCoupon和PercentageCoupon类,并且直接调用他的applyCoupon方法就行了。如:

java
public class Main {
    public static void main(String[] args) {
        Coupon percentageCoupon = new PercentageCoupon();
        percentageCoupon.applyCoupon();

        System.out.println("----------------");

        Coupon fixedAmountCoupon = new FixedAmountCoupon();
        fixedAmountCoupon.applyCoupon();
    }
}