2. 概述

本教程将深入探讨模板方法模式——GoF设计模式中最常用的模式之一。
它通过将算法逻辑封装在单个方法中,让复杂算法的实现变得简单粗暴

3. 核心实现

通过一个计算机组装的示例来演示模板方法模式的工作原理。根据模式定义,**算法结构将在基类中定义,该基类声明模板方法 build()**:

public abstract class ComputerBuilder {
    
    // ...
    
    public final Computer buildComputer() {
        addMotherboard();
        setupMotherboard();
        addProcessor();
        return new Computer(computerParts);
    }
   
    public abstract void addMotherboard();
    public abstract void setupMotherboard();
    public abstract void addProcessor();
    
    // ...
}

ComputerBuilder 类通过声明添加和配置组件的方法(如主板和处理器),勾勒出计算机组装的步骤
这里,**build() 方法就是模板方法**,它定义了组装计算机的算法步骤,并返回完全初始化的 Computer 实例。
⚠️ 注意:该方法被声明为 final 以防止被子类覆盖。

4. 实战演示

有了基类后,我们创建两个子类:一个组装"标准"计算机,另一个组装"高端"计算机:

public class StandardComputerBuilder extends ComputerBuilder {

    @Override
    public void addMotherboard() {
        computerParts.put("Motherboard", "Standard Motherboard");
    }
    
    @Override
    public void setupMotherboard() {
        motherboardSetupStatus.add(
          "Screwing the standard motherboard to the case.");
        motherboardSetupStatus.add(
          "Pluging in the power supply connectors.");
        motherboardSetupStatus.forEach(
          step -> System.out.println(step));
    }
    
    @Override
    public void addProcessor() {
        computerParts.put("Processor", "Standard Processor");
    }
}

高端计算机组装实现:

public class HighEndComputerBuilder extends ComputerBuilder {

    @Override
    public void addMotherboard() {
        computerParts.put("Motherboard", "High-end Motherboard");
    }
    
    @Override
    public void setupMotherboard() {
        motherboardSetupStatus.add(
          "Screwing the high-end motherboard to the case.");
        motherboardSetupStatus.add(
          "Pluging in the power supply connectors.");
        motherboardSetupStatus.forEach(
          step -> System.out.println(step));
    }
    
    @Override
    public void addProcessor() {
         computerParts.put("Processor", "High-end Processor");
    }
}

✅ 优势:我们无需关心整个组装流程,只需实现各个步骤的具体逻辑。
实际调用示例:

new StandardComputerBuilder()
  .buildComputer();
  .getComputerParts()
  .forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v));
        
new HighEndComputerBuilder()
  .buildComputer();
  .getComputerParts()
  .forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v));

5. Java核心库中的模板方法

该模式在Java核心库中被广泛使用,典型代表包括:

  • java.util.AbstractList
  • java.util.AbstractSet

AbstractList 为例,它提供了 List 接口的骨架实现。
模板方法 addAll() 虽未显式声明为 final,但符合模式特征:

public boolean addAll(int index, Collection<? extends E> c) {
    rangeCheckForAdd(index);
    boolean modified = false;
    for (E e : c) {
        add(index++, e);
        modified = true;
    }
    return modified;
}

开发者只需实现 add() 方法:

public void add(int index, E element) {
    throw new UnsupportedOperationException();
}

❌ 踩坑点:程序员必须负责提供在指定索引处添加元素的实现(算法中的可变部分)。

6. 总结

本文展示了模板方法模式的原理及其在Java中的实现方式。
该模式通过继承实现代码复用和解耦,但需要权衡继承带来的局限性。
所有示例代码均可在 GitHub 获取。


原始标题:Implementing the Template Method Pattern in Java | Baeldung