Head First Design Patterns -模板方法模式

什么是模板方法模式

在一个方法中定义一个算法的骨架,而把一些步骤延迟到子类。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。
这些算法步骤中的一个或者多个被定义为抽象的,由子类实现。

类图

在这里插入图片描述

代码

书中用泡茶和泡咖啡作为例子,比较了他们的共同点与不同点,从而做抽象。

泡咖啡的步骤:

  1. 把水煮沸
  2. 用沸水冲泡咖啡
  3. 把咖啡倒进杯子
  4. 加糖和奶

泡茶的步骤:

  1. 把水煮沸
  2. 用沸水浸泡茶叶
  3. 把茶倒进杯子
  4. 加柠檬

从上面可以看出,泡咖啡和泡茶的基本流程是一样的,而且其中把水煮沸的动作也是一样的

由上面的分析可以抽象出,代码如下

顶层抽象类的设计

public abstract class Beverage {
    final void prepareRecipe() { //冲泡方法,定义为final,防止子类更改顺序
        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 customerWantsConditions() {  // 钩子函数
		return true; //默认是添加的,子类可以覆盖这个方法
	}
}

Tea

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

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

Coffee

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

    @Override
    void addCondiments() {
        System.out.println("adding sugar and milk");
    }
}

应用

java API中很多地方会用到模板方法的思想,但使用形式不是完全跟书上类似

下面是一个Arrays.sort()的使用

鸭子类

public class Duck implements Comparable<Duck>{
    private String name;

    private int weight;

    public Duck(String name, int weight) {
        this.name = name;
        this.weight = weight;
    }

    @Override
    public String toString() {
        return name + " " + weight;
    }

    @Override
    public int compareTo(Duck other) {
        return Integer.compare(this.weight, other.weight);
    }

对鸭子进行排序

public class DuckStoreTest {
    public static void main(String[] args) {
        Duck[] ducks = {
          new Duck("a", 5),
          new Duck("b", 9),
          new Duck("c", 3)
        };

        System.out.println("Before sort");
        display(ducks);

        Arrays.sort(ducks); 

        System.out.println("After sort");
        Arrays.sort(ducks);
        display(ducks);
    }

    public static void display(Duck[] ducks) {
        for (Duck d : ducks) {
            System.out.println(d);
        }
    }
}

Arrays.sort()是一个静态方法,这里用户类Duck实现了Comparable的方法,但是并不是通过继承父类的方式类实现。

设计原则

好莱坞原则:不要打电话给我们,我们会打电话给你们。强调了是高层组件去调用低层组件,低层子组件会参与计算,但是不直接调用高层组件。

优点

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

提供了一种代码复用的重要技巧

工厂方法是模板方法的一个特例

策略模式和模板方法模式都是封装算法,但是前者是通过组合,而后者是通过继承。

相关推荐

  1. 设计模式-模板方法模式

    2024-03-23 17:16:03       66 阅读
  2. 【设计模式模板方法模式

    2024-03-23 17:16:03       54 阅读
  3. 设计模式——模板方法模式

    2024-03-23 17:16:03       61 阅读
  4. 设计模式: 模板方法模式

    2024-03-23 17:16:03       44 阅读
  5. 设计模式---模板方法模式

    2024-03-23 17:16:03       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-23 17:16:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-23 17:16:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-23 17:16:03       82 阅读
  4. Python语言-面向对象

    2024-03-23 17:16:03       91 阅读

热门阅读

  1. 面试(二)

    2024-03-23 17:16:03       35 阅读
  2. odoo中,使用paramiko库ssh连接Linux

    2024-03-23 17:16:03       37 阅读
  3. AWS ECS安全更新及自动化应对方案

    2024-03-23 17:16:03       36 阅读
  4. Android 封装的工具类

    2024-03-23 17:16:03       37 阅读
  5. Oracle修改Number类型精度报错:ORA-01440

    2024-03-23 17:16:03       41 阅读