0
点赞
收藏
分享

微信扫一扫

HeadFirst设计模式-模板方法模式

龙毓七七 2022-03-12 阅读 49

定义

模板方法模式,在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

实例

以星巴克咖啡师训练手册为例。

星巴克咖啡冲泡法

(1)把水煮沸

(2)用沸水冲泡咖啡

(3)把咖啡倒进杯子

(4)加糖和牛奶

星巴克茶冲泡法

(1)把水煮沸

(2)用沸水浸泡茶叶

(3)把茶倒进杯子

(4)加柠檬

咖啡和茶的冲泡法大致上一样的。如果分开实现咖啡和茶的冲泡方法,则会发现有不少重复代码。既然咖啡和茶是如此地相似,我们应该将共同的部分抽取出来,放进一个基类中。

// 统称为咖啡因饮料
public abstract class CaffeineBeverage {
    
    final void prepareRecipe() {
        // 把水煮沸
        boilWater();
        // 用热水泡咖啡或茶
        brew();
        // 把饮料倒进杯子
        pourInCup();
        // 在饮料内加入适当的调料
        addCondiments();
    }
    
    // 将咖啡和茶做法不一样的设为抽象类,让子类去实现
    abstract void brew();
    
    abstract void addCondiments();
    
    // 相同做法的抽取到模板类中实现
    void boilWater() {
        System.out.println("Boiling water");
    }
    
    void pourInCup() {
        System.out.println("Pouring into cup");
    }
}

咖啡具体实现:

public class Coffee extends CaffeineBeverage {
    public void brew() {
        System.out.println("Drepping Coffee through filter");
    }
    public void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }
}

茶具体实现:

public class Tea extends CaffeineBeverage {
    public void brew() {
        System.out.println("Steeping the tea");
    }
    public void addCondiments() {
        System.out.println("Adding Lemon");
    }
}

对模板方法进行挂钩

钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩。要不要挂钩,由子类自行决定。

例如,对咖啡因饮料进行挂钩:

public abstract class CaffeineBeverageWithHook {
    
    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;
    }
}

小结

  1. 模板方法定义了算法的步骤,把这些步骤的实现延迟到子类。

  2. 模板方法模式为我们提供了一个代码复用的重要技巧。

  3. 模板方法的抽象类可以定义具体方法、抽象方法和钩子。

  4. 抽象方法由子类实现。

  5. 钩子是一种方法,它在抽象类中不做事,或者只做默认的事情,子类可以选择要不要去覆盖它。

  6. 为了防止子类改变模板方法中的算法,可以将模板方法声明为final。

  7. 好莱坞原则告诉我们,将决策权放在高层模板中,以便决定如何以及何时调用底层模块。

  8. 你将在真实世界代码中看到模板方法模式的许多变体,不要期待它们全都是一眼就可以被你认出的。

  9. 策略模式和模板方法模式都封装算法,一个用组合,一个用继承。

  10. 工厂方法是模板方法的一种特殊版本。

举报

相关推荐

0 条评论