java模版方法

7 阅读2分钟

模版模式(Template Pattern)是一种行为设计模式,它在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

模版模式的结构

  • 抽象类(Abstract Class) :定义模版方法(通常为 final,防止子类修改算法结构)和若干抽象方法(由子类实现),也可以包含一些通用实现。
  • 具体子类(Concrete Class) :实现抽象方法,完成特定步骤。

案例:制作饮料

假设我们有制作茶和咖啡的流程,它们的步骤类似:

  1. 烧水
  2. 冲泡(茶用茶叶,咖啡用咖啡粉)
  3. 倒入杯中
  4. 添加调料(茶可能加柠檬,咖啡可能加糖和牛奶)

我们可以用模版模式将相同的步骤放在抽象类中,不同的步骤交给子类实现。

代码示例(Java)

java

// 抽象类:饮料制作流程
abstract class Beverage {
    // 模版方法,定义算法骨架
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

    // 通用步骤
    private void boilWater() {
        System.out.println("烧水");
    }

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

    // 抽象步骤,由子类实现
    protected abstract void brew();
    protected abstract void addCondiments();

    // 钩子方法,子类可以覆盖,用于控制是否执行某些步骤
    protected boolean customerWantsCondiments() {
        return true; // 默认需要调料
    }
}

// 具体子类:茶
class Tea extends Beverage {
    @Override
    protected void brew() {
        System.out.println("浸泡茶叶");
    }

    @Override
    protected void addCondiments() {
        System.out.println("加入柠檬");
    }
}

// 具体子类:咖啡
class Coffee extends Beverage {
    @Override
    protected void brew() {
        System.out.println("冲泡咖啡粉");
    }

    @Override
    protected void addCondiments() {
        System.out.println("加入糖和牛奶");
    }

    // 覆盖钩子方法,决定是否加调料
    @Override
    protected boolean customerWantsCondiments() {
        // 这里可以询问用户,简单返回 true
        return true;
    }
}

// 测试类
public class TemplatePatternDemo {
    public static void main(String[] args) {
        System.out.println("制作茶:");
        Beverage tea = new Tea();
        tea.prepareRecipe();

        System.out.println("\n制作咖啡:");
        Beverage coffee = new Coffee();
        coffee.prepareRecipe();
    }
}

运行结果

text

制作茶:
烧水
浸泡茶叶
倒入杯中
加入柠檬

制作咖啡:
烧水
冲泡咖啡粉
倒入杯中
加入糖和牛奶

模版模式的优点

  • 代码复用:将公共代码放在抽象类中,避免重复。
  • 扩展性:子类只需实现必要步骤,算法结构固定。
  • 控制反转:父类调用子类的方法,实现反向控制。

适用场景

  • 多个类有相同的算法步骤,但部分步骤实现不同。
  • 希望控制子类扩展,不允许修改算法整体结构。
  • 需要提取公共行为到基类,避免代码重复。

模版模式在框架和库中非常常见,例如 Java 的 AbstractListHttpServlet 的 service 方法等。