一、需求分析

  1、应用实例要求

    编写制作豆浆的程序,说明如下:

      •  制作豆浆的流程:选材——>添加配料——>浸泡——>放到豆浆机打碎
      •    通过添加不同的配料,可以制作出不同口味的豆浆
      •    选材、浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的(红豆豆浆、花生豆浆...)

  2、分析与类图

    

二、代码实现

  抽象类:

 1 /**
 2  * 抽象类,表示豆浆
 3  */
 4 public abstract class SoyaMilk {
 5 
 6     /**
 7      *     模板方法,make,模板方法可以做成 final,不让子类去覆盖
 8      */
 9     final void make() {
10         select();
11         addCondiments();
12         soak();
13         beat();
14 
15     }
16 
17     /**
18      * 选材料
19      */
20     void select() {
21         System.out.println("第一步:选择好的新鲜黄豆");
22     }
23 
24     /**
25      * 添加不同的配料,抽象方法
26      */
27     abstract void addCondiments();
28 
29     /**
30      * 浸泡
31      */
32     void soak() {
33         System.out.println("第三步:黄豆和配料开始浸泡,需要三小时");
34     }
35 
36     /**
37      * 打豆浆
38      */
39     void beat() {
40         System.out.println("第四步:黄豆和配料放豆浆机打碎");
41     }
42 
43 }

 

  实现类:

 1 /**
 2  * 红豆豆浆
 3  */
 4 public class BedBeanSoyaMilk extends SoyaMilk{
 5 
 6     @Override
 7     void addCondiments() {
 8         System.out.println("加入上好的红豆");
 9     }
10 }
11 -------------------------------------------------------------
12 public class PeanutSoyaMilk extends SoyaMilk{
13     @Override
14     void addCondiments() {
15         System.out.println("加入上好的花生");
16     }
17 }

 

  客户端:

 1 public class Client {
 2     public static void main(String[] args) {
 3 
 4         //制作红豆豆浆
 5         System.out.println("---制作红豆豆浆---");
 6         SoyaMilk redBeanSoyaMilk = new BedBeanSoyaMilk();
 7         redBeanSoyaMilk.make();
 8 
 9         //制作花生豆浆
10         System.out.println("---制作花生豆浆---");
11         SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
12         peanutSoyaMilk.make();
13     }
14 }

 

三、模板方法模式的钩子方法

  1、钩子方法

    (1)在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事,子类可以视情况要不要覆盖它,该方法称为“钩子”;

    (2)还是上面的示例,我们希望制作纯豆浆,不添加任何的配料,下面使用钩子方法对前面的模板方法进行改造。

  2、代码实现

    修改抽象类:

 1 /**
 2  * 抽象类,表示豆浆
 3  */
 4 public abstract class SoyaMilk {
 5 
 6     /**
 7      *     模板方法,make,模板方法可以做成 final,不让子类去覆盖
 8      */
 9     final void make() {
10         select();
11         if (customerWantCondiments()) {
12             addCondiments();
13         }
14         soak();
15         beat();
16 
17     }
18 
19     /**
20      * 选材料
21      */
22     void select() {
23         System.out.println("第一步:选择好的新鲜黄豆");
24     }
25 
26     /**
27      * 添加不同的配料,抽象方法
28      */
29     abstract void addCondiments();
30 
31     /**
32      * 浸泡
33      */
34     void soak() {
35         System.out.println("第三步:黄豆和配料开始浸泡,需要三小时");
36     }
37 
38     /**
39      * 打豆浆
40      */
41     void beat() {
42         System.out.println("第四步:黄豆和配料放豆浆机打碎");
43     }
44 
45 
46     /**
47      * 钩子方法,决定是否添加配料
48      */
49     boolean customerWantCondiments() {
50         return true;
51     }
52 
53 }

 

    添加一个子类:

 1 public class PureSoyaMilk extends SoyaMilk{
 2     @Override
 3     void addCondiments() {
 4 
 5     }
 6 
 7     @Override
 8     boolean customerWantCondiments() {
 9         return false;
10     }
11 }

 

    客户端:

 1 public class Client {
 2     public static void main(String[] args) {
 3 
 4         //制作红豆豆浆
 5         System.out.println("---制作红豆豆浆---");
 6         SoyaMilk redBeanSoyaMilk = new BedBeanSoyaMilk();
 7         redBeanSoyaMilk.make();
 8 
 9         //制作花生豆浆
10         System.out.println("---制作花生豆浆---");
11         SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
12         peanutSoyaMilk.make();
13 
14         //制作纯豆浆
15         System.out.println("---制作纯豆浆---");
16         SoyaMilk pureSoyaMilk = new PureSoyaMilk();
17         pureSoyaMilk.make();
18     }
19 }

 

posted on 2021-02-06 14:45  格物致知_Tony  阅读(104)  评论(0编辑  收藏  举报