前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >框架创建中常见设计模式-模板方法模式

框架创建中常见设计模式-模板方法模式

作者头像
杨小杰
发布2019-07-04 16:27:34
3240
发布2019-07-04 16:27:34
举报
文章被收录于专栏:JAVA知识总结与分享

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

设计_原则

好莱坞原则:别调用我们,我们会调用你。

先来看下简单的代码实现:

定义一个父类:果汁流程制作

代码语言:javascript
复制
 1package com.templateModePattern.parentClass;
 2
 3/**
 4 * @program: test
 5 * @description: 果汁的制造简单流程:--》清洗水果 --》放入修饰材料--》放入榨汁机中
 6 *               因为放入修饰材料的流程,各个果汁不一样,所以放入子类去实现
 7 * @author: Mr.Yang
 8 * @create: 2018-12-22 13:19
 9 **/
10public  abstract  class FruitJuiceParent {
11
12    /**
13     * 果汁的制造流程(当作固定流程,不会变),这个方法不希望子类去覆盖,
14     *子类只需要实现putMaterial()方法就行,声明为final,骨架方法
15     */
16    public  final void makeFruitJuice(){
17        cleanIts();
18        putMaterial();
19        putMachine();
20    }
21
22    protected  abstract void putMaterial();
23
24    /**
25     * 清洗水果
26     */
27    protected  void cleanIts(){
28        System.out.println("clean fruit");
29    }
30
31    /**
32     * 放入榨汁机中
33     */
34    protected  void putMachine(){
35        System.out.println("put machine");
36    }
37}

子类苹果汁,实现父类未实现的方法

代码语言:javascript
复制
 1package com.templateModePattern.subClass;
 2
 3import com.templateModePattern.parentClass.FruitJuiceParent;
 4
 5/**
 6 * @program: test
 7 * @description: 苹果汁
 8 * @author: Mr.Yang
 9 * @create: 2018-12-22 13:26
10 **/
11public class AppleFruitJuice extends FruitJuiceParent {
12
13    /**
14     * 在苹果汁放入蜂蜜,味道更好
15     */
16    public void putMaterial() {
17        System.out.println("Put in honey");
18    }
19
20}

子类西瓜汁,实现父类未实现的方法

代码语言:javascript
复制
 1package com.templateModePattern.subClass;
 2
 3import com.templateModePattern.parentClass.FruitJuiceParent;
 4
 5/**
 6 * @program: test
 7 * @description: 西瓜汁
 8 * @author: Mr.Yang
 9 * @create: 2018-12-22 13:29
10 **/
11public class WatermelonFruitJuice extends FruitJuiceParent {
12
13    /**
14     * 放入牛奶,味道更好
15     */
16    public void putMaterial() {
17        System.out.println("put in milk");
18    }
19}

挂钩

钩子是一种被声明在抽象类中的方法,但只有空的或者默认实现,钩子的存在,可以让子类有能力对算法的不同点进行挂钩,要不要挂钩,由子类自行决定。

在方法中加入挂钩代码实现

父类加入判断,如果true,去执行,让子类去具体实现该方法,做处理

代码语言:javascript
复制
 1package com.templateModePattern.parentClass;
 2
 3/**
 4 * @program: test
 5 * @description: 果汁的制造简单流程:--》清洗水果 --》放入修饰材料--》放入榨汁机中
 6 *               因为放入修饰材料的流程,各个果汁不一样,所以放入子类去实现
 7 * @author: Mr.Yang
 8 * @create: 2018-12-22 13:19
 9 **/
10public  abstract  class FruitJuiceParent {
11
12    /**
13     * 果汁的制造流程(当作固定流程,不会变),这个方法不希望子类去覆盖,
14     * 子类只需要实现putMaterial()方法就行,声明为final
15     */
16    public final void makeFruitJuice(){
17        cleanIts();
18        if(isPutMaterIal()){
19            putMaterial();
20        }
21        putMachine();
22    }
23
24    protected abstract void putMaterial();
25
26    /**
27     * 清洗水果
28     */
29    protected void cleanIts(){
30        System.out.println("clean fruit");
31    }
32
33    /**
34     * 放入榨汁机中
35     */
36    protected void putMachine(){
37        System.out.println("put machine");
38    }
39
40    /**
41     * 父类增加判断
42     * @return
43     */
44    protected boolean isPutMaterIal(){
45        return true;
46    }
47}

苹果汁子类让用户去做选择

代码语言:javascript
复制
 1package com.templateModePattern.subClass;
 2
 3import com.templateModePattern.parentClass.FruitJuiceParent;
 4import org.apache.commons.lang3.StringUtils;
 5
 6import java.io.BufferedReader;
 7import java.io.IOException;
 8import java.io.InputStreamReader;
 9
10/**
11 * @program: test
12 * @description: 苹果汁
13 * @author: Mr.Yang
14 * @create: 2018-12-22 13:26
15 **/
16public class AppleFruitJuice extends FruitJuiceParent {
17
18    /**
19     * 在苹果汁放入蜂蜜,味道更好
20     */
21    public void putMaterial() {
22        System.out.println("Put in honey");
23    }
24
25    /**
26     * 在子类覆盖它,让用户去选择
27     * @return
28     */
29    @Override
30    protected boolean isPutMaterIal() {
31        String userInput = getUserInput();
32        if(userInput.toLowerCase().startsWith("y")){
33            return true;
34        }else{
35            return false;
36        }
37    }
38
39    /**
40     * 得到用户输入的内容
41     * @return
42     */
43    private String getUserInput(){
44        String readString=null;
45        System.out.println("Do you want honey(y/n)?");
46        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
47        try {
48            readString = br.readLine();
49        } catch (IOException e) {
50            System.out.println("---异常---"+e);
51        }
52        if(StringUtils.isEmpty(readString)){
53            return "N";
54        }else{
55            return readString;
56        }
57    }
58}

西瓜汁子类让用户去做选择

代码语言:javascript
复制
 1package com.templateModePattern.subClass;
 2
 3import com.templateModePattern.parentClass.FruitJuiceParent;
 4import org.apache.commons.lang3.StringUtils;
 5
 6import java.io.BufferedReader;
 7import java.io.IOException;
 8import java.io.InputStreamReader;
 9
10/**
11 * @program: test
12 * @description: 西瓜汁
13 * @author: Mr.Yang
14 * @create: 2018-12-22 13:29
15 **/
16public class WatermelonFruitJuice extends FruitJuiceParent {
17
18    /**
19     * 放入牛奶,味道更好
20     */
21    public void putMaterial() {
22        System.out.println("put in milk");
23    }
24
25
26    /**
27     * 在子类覆盖它,让用户去选择
28     * @return
29     */
30    @Override
31    protected boolean isPutMaterIal() {
32        String userInput = getUserInput();
33        if(userInput.toLowerCase().startsWith("y")){
34            return true;
35        }else{
36            return false;
37        }
38    }
39
40    /**
41     * 得到用户输入的内容
42     * @return
43     */
44    private String getUserInput(){
45        String readString=null;
46        System.out.println("Do you want milk(y/n)?");
47        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
48        try {
49            readString = br.readLine();
50        } catch (IOException e) {
51            System.out.println("---异常---"+e);
52        }
53        if(StringUtils.isEmpty(readString)){
54            return "N";
55        }else{
56            return readString;
57        }
58    }
59}

制造无添加草莓汁

代码语言:javascript
复制
 1package com.templateModePattern.subClass;
 2
 3import com.templateModePattern.parentClass.FruitJuiceParent;
 4
 5/**
 6 * @program: test
 7 * @description: 草莓汁,无添加
 8 * @author: Mr.Yang
 9 * @create: 2018-12-22 13:46
10 **/
11public class StrawberryFruitJuice extends FruitJuiceParent {
12
13    protected void putMaterial() {
14
15    }
16
17    @Override
18    protected boolean isPutMaterIal() {
19        return false;
20    }
21}
测试结果:
代码语言:javascript
复制
 1____________苹果汁制作开始____________
 2clean fruit
 3Do you want honey(y/n)?
 4y
 5Put in honey
 6put machine
 7____________苹果汁制作结束____________
 8
 9
10____________草莓汁制作开始____________
11clean fruit
12put machine
13____________草莓汁制作结束____________
14
15
16____________西瓜汁制作____________
17clean fruit
18Do you want milk(y/n)?
19n
20put machine
21____________西瓜汁结束____________

好莱坞原则与依赖倒置原则的区别

依赖倒置提倡避免使用具体类,多使用抽象。 好莱坞原则是用在创建框架或组件上的一种技巧,让底层组件能够被挂钩计算中,又不会让高层组件依赖低层组件。

重点内容与比较

1.模板方法定义了算法的步骤,将步骤的实例延迟到子类 2.提供了一种代码复用的技巧 3.钩子的了解与使用 4.好莱坞原则提倡将决策权放到高层(父类) 5.策略模式和模板方法模式都封装算法,一个用组合,一个用继承

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-12-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JAVA知识总结与分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 设计_原则
    • 先来看下简单的代码实现:
    • 挂钩
      • 在方法中加入挂钩代码实现
        • 测试结果:
        • 好莱坞原则与依赖倒置原则的区别
        • 重点内容与比较
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档