模板方法模式

61 阅读1分钟

模板方法模式

如果你想做一道菜,那么通常需要放油,爆香,放菜,放盐,翻炒,放调料,关火,起锅这几个步骤。这听起来像一个接口,只需要先定义好这几个方法即可。但是单纯的接口无法定义各个行为的执行顺序。

定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的接口即可重新定义该算法的某些特定步骤。

所以我们需要一个抽象类,既可以定义好各个步骤的执行顺序,又可以让子类重写各个步骤的具体逻辑。

// 抽象类,定义饮料制作的模板方法
abstract class Beverage {

    // 模板方法,定义了制作饮料的流程
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) { // 钩子方法
            addCondiments();
        }
    }

    // 通用的步骤,所有饮料都需要的
    public void boilWater() {
        System.out.println("Boiling water");
    }

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

    // 需要子类实现的抽象方法,不同饮料的具体制作方式
    public abstract void brew();

    public abstract void addCondiments();

    // 钩子方法:子类可以覆盖,也可以不覆盖
    public boolean customerWantsCondiments() {
        return true;
    }
}

具体的子类实现:

// 茶的制作方法
class Tea extends Beverage {

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

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

    @Override
    public boolean customerWantsCondiments() {
        // 客户决定是否加调料
        return false;  // 例如,这里可以表示客户不想加调料
    }
}

// 咖啡的制作方法
class Coffee extends Beverage {

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

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