Skip to content

模板方法模式

模板方法设计模式是一种行为设计模式,它定义了一个操作中的算法骨架,而将一些步骤延迟到子类中实现。模板方法使得子类可以重新定义某个步骤的操作,而不改变算法的结构。这种模式是一种非常实用的代码复用技术,特别是在处理那些存在固定流程但具体步骤可能不同的场景。

类图

模板方法模式

基本组成部分

  • 抽象类(Abstract Class):它定义了一个或多个模板方法,这些模板方法定义了算法的骨架。抽象类还声明了一些抽象操作,子类需要具体实现这些操作。
  • 具体子类(Concrete Class):实现抽象类所声明的抽象操作,以完成算法中各个步骤的具体功能。

应用场景

《大话设计模式》

  • 当我们要完成某一个细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的而实现可能不同时
  • 当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。

优点

  1. 提高代码复用性:通过将公共部分的代码放在抽象类中,减少代码重复。
  2. 易于扩展:新增具体子类时,只需要实现必要的步骤,无需改变整体算法结构。
  3. 遵循开闭原则:允许你新增行为,而无需修改现有类的代码。

示例

java
// 抽象类:饮料制作流程
abstract class Beverage {
    // 模板方法,定义冲泡流程
    final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

    // 具体步骤由子类实现
    abstract void brew();
    abstract void addCondiments();

    // 公共步骤实现,烧开水
    void boilWater() {
        System.out.println("Boiling water");
    }

    void pourInCup() {
        System.out.println("Pouring into cup");
    }

    // 钩子方法,子类可选择是否覆盖
    boolean customerWantsCondiments() {
        return true;
    }
}

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

    @Override
    void addCondiments() {
        System.out.println("Adding sugar and milk to coffee");
    }
}

// 具体子类:茶
class Tea extends Beverage {
    @Override
    void brew() {
        System.out.println("Steeping the tea");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding lemon");
    }

    // 重写了钩子方法
    @Override
    boolean customerWantsCondiments() {
        return false; // 假设有些顾客喝茶时不想要添加物
    }
}

public class TemplateMethodPatternDemo {
    public static void main(String[] args) {
        Beverage coffee = new Coffee();
        coffee.prepareRecipe();

        System.out.println();

        Beverage tea = new Tea();
        tea.prepareRecipe();
    }
}

Released under the MIT License.