📜  模板方法设计模式(1)

📅  最后修改于: 2023-12-03 15:10:57.396000             🧑  作者: Mango

模板方法设计模式介绍

模板方法设计模式(Template Method Design Pattern)是一种行为型设计模式,用于定义在一个抽象类中算法的骨架,而将一些步骤延迟到子类中实现。

模式组成
抽象类

抽象类(Abstract Class)定义了一个模板方法 method(),该方法定义了一个算法的骨架。此外,该类还定义了一些抽象方法,这些抽象方法必须在子类中实现。

public abstract class AbstractClass {

    public void method() {
        // 实现某些公共逻辑
        doSomething1();
        // 留给子类实现的逻辑
        doSomething2();
        // 留给子类实现的逻辑
        doSomething3();
    }

    public abstract void doSomething2();

    public abstract void doSomething3();

}
具体类

具体类(Concrete Class)是抽象类的子类,它实现了在抽象类中定义的抽象方法。

public class ConcreteClass extends AbstractClass {

    @Override
    public void doSomething2() {
        // 实现具体逻辑2
    }

    @Override
    public void doSomething3() {
        // 实现具体逻辑3
    }
    
}
模式应用场景
一次性实现一个算法的不变部分,并将可变部分留给子类来实现。

在模板方法模式中,抽象类定义了一个算法的骨架,而具体子类实现了算法的具体步骤。

重构框架或库等某一部分的代码。

如在Spring框架中使用了模板方法设计模式,它定义了一些基础类和接口,让用户实现其中的方法,从而构建自己的应用程序。

模式优缺点
优点:
  • 封装具体细节,使代码更加灵活。
  • 提高代码复用性。
  • 实现了反向控制。
缺点:
  • 模板方法定义了一种固定的算法框架,限制了子类的行为。
  • 程序员必须理解模板方法的结构才能够实现子类。
模式实现

在使用模板方法设计模式时,需要遵循以下步骤:

  1. 定义一个抽象类,该类声明一个模板方法,同时定义了一些抽象方法,这些抽象方法将会在子类中实现。
  2. 定义具体的子类,实现在抽象类中定义的抽象方法。
  3. 调用模板方法。
模式示例
public abstract class CaffeineBeverage {

    // 模板方法
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
        hook();
    }

    // 封装固定算法中的不变部分(私有化)
    private void boilWater() {
        System.out.println("Boiling water");
    }

    // 封装可变部分
    public abstract void brew();

    // 封装固定算法中的不变部分(私有化)
    private void pourInCup() {
        System.out.println("Pouring into cup");
    }

    // 封装可变部分
    public abstract void addCondiments();

    // 钩子方法
    public void hook() {}

}


public class Coffee extends CaffeineBeverage {

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

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

}


public class Tea extends CaffeineBeverage {

    @Override
    public void brew() {
        System.out.println("Steeping the tea");
    }

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

    @Override
    public void hook() {
        System.out.println("Add ginger if desired.");
    }

}


public class Main {

    public static void main(String[] args) {
        CaffeineBeverage coffee = new Coffee();
        CaffeineBeverage tea = new Tea();

        System.out.println("Making coffee...");
        coffee.prepareRecipe();

        System.out.println("\nMaking tea...");
        tea.prepareRecipe();
    }

}

输出结果:

Making coffee...
Boiling water
Dripping Coffee through filter
Pouring into cup
Adding Sugar and Milk

Making tea...
Boiling water
Steeping the tea
Pouring into cup
Adding Lemon
Add ginger if desired.

这个例子中,我们定义了一个抽象类 CaffeineBeverage,定义了两个抽象方法 brew()addCondiments(),并实现了一个模板方法 prepareRecipe()。具体的实现由子类 CoffeeTea 实现。Tea 还重写了一个钩子方法 hook(),以提供额外的功能。我们可以看到,在调用 prepareRecipe() 方法时,每个子类都实现了自己的特定行为,实现了一种固定算法的框架。这里的算法框架指的是泡茶或咖啡的顺序,而每个子类都定义了自己特有的具体过程。