常用设计模式9:模板方法模式(Java)

模板方法模式(Template Method Pattern)

1. 简介

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

2. 为什么使用模板方法模式?

  • 代码复用:将公共代码放在抽象类中,避免重复。
  • 扩展性:可以轻松地增加和修改算法步骤。
  • 反向控制:父类调用子类的操作,而不是子类调用父类的操作。
  • 遵循"好莱坞原则":不要调用我们,我们会调用你。

3. 模板方法模式的结构

模板方法模式主要包含以下角色:

  1. AbstractClass(抽象类):定义了一系列抽象操作,以及一个模板方法。
  2. ConcreteClass(具体类):实现抽象类中的抽象操作。

4. Java 实现示例

下面通过一个简单的饮料制作过程来说明模板方法模式:

4.1 定义抽象类

public abstract class Beverage {
    
    // 模板方法
    public final void prepareBeverage() {
        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;
    }
}

4.2 实现具体类

public class Coffee extends Beverage {
    @Override
    void brew() {
        System.out.println("Dripping Coffee through filter");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }
}

public 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; // 假设茶不需要调料
    }
}

4.3 客户端代码

public class BeverageTestDrive {
    public static void main(String[] args) {
        Tea tea = new Tea();
        Coffee coffee = new Coffee();
        
        System.out.println("Making tea...");
        tea.prepareBeverage();
        
        System.out.println("\nMaking coffee...");
        coffee.prepareBeverage();
    }
}

5. 模板方法模式的优缺点

优点:

  • 提高代码复用性
  • 提供了一种反向控制结构
  • 符合"开闭原则"

缺点:

  • 每个不同的实现都需要一个子类,可能会导致类的数量增加
  • 限制了算法的灵活性

6. 适用场景

  • 当只希望客户端扩展某个特定算法步骤,而不是整个算法或其结构时。
  • 当有多个类包含几乎相同的算法,但有一些细微的差异时。

7. 模板方法与策略模式的区别

虽然模板方法模式和策略模式都是处理算法变化的设计模式,但它们有以下区别:

  1. 继承 vs 组合:模板方法使用继承来改变部分算法,策略模式使用组合来改变整个算法。
  2. 算法结构:模板方法固定算法结构,策略模式允许完全替换算法。
  3. 控制反转:模板方法典型地使用"好莱坞原则",而策略模式通常不会。

8. Java 标准库中的模板方法

Java 标准库中有很多使用模板方法模式的例子:

  • java.io.InputStream, java.io.OutputStream, java.io.Readerjava.io.Writer 的所有非抽象方法。
  • java.util.AbstractList, java.util.AbstractSetjava.util.AbstractMap 的非抽象方法。

9. 总结

模板方法模式是一种简单但强大的设计模式,它通过将算法的结构定义在一个方法中,并将某些步骤的实现延迟到子类中,提供了一种灵活的方式来改变算法的部分实现。这种模式在框架设计中特别有用,因为它允许框架定义标准流程,同时允许用户通承来定制特定的步骤。然而,使用这种模式时需要注意避免创建过多的子类,并确保抽象类中的模板方法不会过于复杂。

posted @ 2024-08-14 12:07  KenWan  阅读(8)  评论(0编辑  收藏  举报