模板方法的定义
模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。
场景
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策略模式
|
模板方法模式 |
策略模式 |
定义 |
定义一个算法大纲,由子类定义其中算法的某些步骤 |
封装可互换的行为,使用委托来决定要采用哪一个行为 |
实现 |
通过继承 |
通过对象组合 |