模板方法模式:在一个方法中定义一个算法的骨架,而将这个算法中的一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
冲泡饮料:咖啡的冲泡需要四个步骤 : 1.烧一壶热水 2.用热水冲泡咖啡粉 3.把咖啡倒进杯子中 4.加糖和牛奶
茶的冲泡也需要四个步骤 : 1.烧一壶热水 2.用热水冲泡茶叶 3.把茶倒进杯子中 4.加柠檬
通过对比可以发现 在咖啡冲泡和茶的冲泡过程中,两者的流程和手法基本都是一样的,也就是算法流程相同。
所以我们可以将这个流程 泛化成这样四个步骤:1.烧热水 2.冲泡 3.把饮料倒进杯子 4.加调料
这样定义一个饮料父类,提供一个模板方法,让冲泡过程按着1234的步骤进行,相同的步骤13方法让子类去继承,不同的24方法写成抽象的方法,让子类自己去实现。
类图如下:
父类 CaffeineBeverage
1 /** 2 * 这是父类 咖啡因饮料 3 * @author wly 4 */ 5 public abstract class CaffeineBeverage { 6 /** 7 * 这是父类的模板方法 ,使用了final关键字,是希望子类只能继承这个方法,不能重写这个方法以免破坏了算法的流程 8 */ 9 public final void prepareRecipe() 10 { 11 boilWater(); 12 brew(); 13 pourInCup(); 14 addCondiments(); 15 } 16 /** 17 * 这是步骤1,冲泡热水,让子类去继承 18 */ 19 public void boilWater() 20 { 21 System.out.println("热水已经准备好了....."); 22 } 23 /** 24 * 这是步骤2,冲泡饮料,让子类自己去实现 25 */ 26 public abstract void brew(); 27 /** 28 * 这是步骤3,将饮料倒进杯子中,让子类去继承 29 */ 30 public void pourInCup() 31 { 32 System.out.println("将冲泡好的饮料倒进杯子中....."); 33 } 34 /** 35 * 这是步骤4,加调料,让子类自己去实现 36 */ 37 public abstract void addCondiments(); 38 39 }
子类 Caffe
1 /** 2 * 子类 Caffe 3 * @author wly 4 * 5 */ 6 public class Caffe extends CaffeineBeverage { 7 //模板方法 ,和步骤1,3方法 都从父类继承而来 8 /** 9 * 步骤2,冲泡饮料 ,子类自己实现 10 */ 11 @Override 12 public void brew() { 13 System.out.println("用沸水,来冲泡咖啡粉....."); 14 15 } 16 /** 17 * 步骤4,添加调料,子类自己实现 18 */ 19 @Override 20 public void addCondiments() { 21 System.out.println("添加糖和牛奶....."); 22 23 } 24 }
子类 Tea
1 /** 2 * 子类 Tea 3 * @author wly 4 * 5 */ 6 public class Tea extends CaffeineBeverage { 7 //模板方法 ,和步骤1,3方法 都从父类继承而来 8 /** 9 * 步骤2,冲泡饮料 ,子类自己实现 10 */ 11 @Override 12 public void brew() { 13 System.out.println("用沸水,来冲泡茶叶....."); 14 } 15 /** 16 * 步骤4,添加调料,子类自己实现 17 */ 18 @Override 19 public void addCondiments() { 20 System.out.println("添加柠檬....."); 21 } 22 }
最后提供一个测试类:
1 public class TestClass { 2 3 /** 4 * @param args 5 */ 6 public static void main(String[] args) { 7 CaffeineBeverage caffe = new Caffe(); 8 caffe.prepareRecipe(); 9 System.out.println("**************************"); 10 CaffeineBeverage tea = new Tea(); 11 tea.prepareRecipe(); 12 13 } 14 15 }
输出结果: