什么是模板方法模式?

  模板方法就是为多种类似业务提供一个算法执行的统一框架,把这些业务中共同的部分抽取出来进行具体实现,而某些业务中特定的需求推迟到子类中进行重写实现。

模板方法模式如何实现?

  场景实例:就拿制备咖啡和热茶两种业务进行比较,两者有共同的业务步骤如煮沸热水和把泡制好导入杯中,也有特定的业务步骤即个性化需求如泡制咖啡和茶的材料时间是不同的,成品后加入的调味品也不同。

Java设计模式(04-- 模板方法模式)

用抽象基类定义算法框架 RefreshBeverage

 1 package com.imooc.pattern.template;
 2 
 3 /**
 4  * 抽象基类,为其他子类提供一个算法框架
 5  * 提神饮料
 6  * @author zplogo
 7  *
 8  */
 9 public abstract class RefreshBeverage {
10     
11     /*
12      * 制备饮料的模板方法
13      * 封装了所有子类所遵循的算法框架
14      */
15     public final  void prepareBeverageTemplate() { 
16         //步骤一 将水煮沸 
17         boilWater();
18         //步骤二  泡制饮料
19         brew();
20         //步骤三 将饮料倒入杯中
21         pourInCup();
22         if(isCustomerWantsCondiments()){
23             //步骤四 加入调味料
24             addCondiments();
25         }
26     }
27     /*
28      * Hook 钩子函数,提供一个空的或者默认的实现
29      * 子类重写该方法,可以自行决定是否挂钩以及如何挂钩
30      */
31     protected boolean isCustomerWantsCondiments() {
32         return true;
33     }
34 
35     //因为将水煮沸和把饮料倒入杯中对所有子类是共同的行为,所以没必要向子类过多开放,所以方法定义为private,这样我们在进行子类编码时可以减少复杂度。 
36     //这样不需要关注细枝末节,我们只需要关注我们特定业务的实现,这就是模板方法模式的好处。可以封装变与不变,将不变的固化在高层,隐藏其细节。
37     private void boilWater() {
38         System.out.println("将水煮沸");
39     }
40     
41     private void pourInCup() {
42         System.out.println("将饮料倒入杯中");    
43     }
44     
45     /*
46      * 泡制饮料brew()和加入调料品addCondiments()这两个方法我们不知道它们在算法框架中的具体实现,因此定义为抽象方法,我们用protected进行修饰,
47      * 在子类中可见便于进行重写。
48      */
49     protected abstract void brew();
50     
51     protected abstract void addCondiments();
52     
53 }

View Code