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

场景
Starbuzz饮品店培训
场景描述
Starbuzz内部有两种饮料:咖啡和茶。需要对新加入的师傅进行饮品制作的培训,已知:a)咖啡和茶都有各自的冲泡方式,b)咖啡和茶的冲泡有相同和不同的步骤。如何才能简化培训时的步骤:难道一定要培训完一遍咖啡的制作过程,再培训一遍茶的制作过程吗?
| Starbuzz咖啡冲泡法 | 
Starbuzz茶冲泡法 | 
1.把水煮沸; 2.用沸水冲泡咖啡; 3.把咖啡倒进杯子; 4.加糖和牛奶; | 
1.把水煮沸; 2.用沸水浸泡茶叶; 3.把茶倒进杯子; 4.加柠檬; | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | public class Coffee {     void prepareRecipe() {         boilWater();         brewCoffeeGrinds();         pourInCup();         addSugarAndMilk();     }     public void boilWater() {         System.out.println("Boiling water");     }     public void brewCoffeeGrinds() {         System.out.println("Dripping Coffee through filter");     }     public void pourInCup() {         System.out.println("Pouring into cup");     }     public void addSugarAndMilk() {         System.out.println("Adding Sugar and Milk");     } }
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | public class Tea {     void prepareRecipe() {         boilWater();         steepTeaBag();         pourInCup();         addLemon();     }     public void boilWater() {         System.out.println("Boiling water");     }     public void steepTeaBag() {         System.out.println("Steeping the tea");     }     public void addLemon() {         System.out.println("Adding Lemon");     }     public void pourInCup() {         System.out.println("Pouring into cup");     } }
  | 
 
方案
注意这两种冲泡法都采用了相同的算法:
- 把水煮沸;
 
- 用热水泡咖啡或茶;
 
- 把饮料倒进杯子;
 
- 在饮料内加入适当调料;
 
对prepareRecipe()方法进行如下抽象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | 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");     } }
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | public class Tea extends CaffeineBeverage {     public void brew() {         System.out.println("Steeping the tea");     }     public void addCondiments() {         System.out.println("Adding Lemon");     } }
  public class Coffee extends CaffeineBeverage {     public void brew() {         System.out.println("Dripping Coffee through filter");     }     public void addCondiments() {         System.out.println("Adding Sugar and Milk");     } }
  | 
 
以上抽象类CaffeineBeverage中的prepareRecipe()方法就是模版方法:
- 首先,它是一个方法;
 
- 它用作一个算法的模板,定义了算法的步骤,在这个例子中,算法就是
制作咖啡因饮料;算法内每一个步骤都被一个方法代表了,例如boilWater()、brew()、pourInCup()、addCondiments(); 
- 算法内的一些方法在超类中处理,一些方法则是在子类中处理;
 
模板方法模式VS策略模式
 | 
模板方法模式 | 
策略模式 | 
| 定义 | 
定义一个算法大纲,由子类定义其中算法的某些步骤 | 
封装可互换的行为,使用委托来决定要采用哪一个行为 | 
| 实现 | 
通过继承 | 
通过对象组合 |