设计模式之模板方法
设计模式之模板方法
不正经啊不正经 发表于3年前
设计模式之模板方法
  • 发表于 3年前
  • 阅读 24
  • 收藏 1
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

摘要: 设计模式之模板方法

一、定义

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤.

二、核心思想

1、这个模式是用来创建一个算法的模板

2、模板方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现

3、确保算法的结构保持不变,同时由子类提供部分实现

三、相关设计原则

好莱坞原则

1、别调用(打电话给)我们,我们会调用(打电话给)你

2、用于防止依赖腐败

3、要不要用你,高层组件说了算

4、好莱坞原则让底层组件被挂钩进计算中,而又不会让高层组件依赖底层组件 

钩子

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

2、有了钩子,我们可以让模板方法中的程序决定是否调用模板方法中的某些方法


四、使用场景

1、茶和咖啡的冲泡方式

茶:(1)把谁煮沸(2)用沸水冲泡咖啡(3)把咖啡倒进杯子(4)加糖和牛奶

咖啡:(1)把谁煮沸(2)用沸水浸泡茶叶(3)把茶倒进杯子(4)加柠檬

2、观察场景

两种冲泡方式有相同的地方,也有不同的地方


五、代码实现

package com.fengshu.limanman;
 
/**
 * 
 * 1、理解模板方法 2、理解好莱坞原则 3、理解钩子的用法
 * 
 * @author 李慢慢
 *
 */
public class Temple {
    public static void main(String[] args) {
        CaffeineBeverage caffeineBeverage = new Coffee();
        caffeineBeverage.pripareRecipe();
    }
}
 
/**
 * 制作咖啡因饮料的模板方法
 *
 */
abstract class CaffeineBeverage {
 
    /**
     * final 确保算法的结构保持不变,也体现了好莱坞设计原则,让子类没办法直接调用父类(高层组件方法),只能由高层组件来调用子类实现的方法
     */
    final void pripareRecipe() {
        boilWater();
        brew();
        pourInCup();
        // 钩子决定子类是否执行模板中的某些方法
        if (needCondiments()) {
            addCondiments();
        }
    }
 
    /**
     * 模板方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现
     */
    abstract void brew();
 
    /**
     * 模板方法将一部分的实现延迟到了子类中
     */
    abstract void addCondiments();
 
    void boilWater() {
        System.out.println("Boiling water");
    }
 
    void pourInCup() {
        System.out.println("Pouring into cup");
    }
 
    /**
     * 使用了钩子默认true,由子类决定是否进行覆盖
     * 
     * @return
     */
    boolean needCondiments() {
        return true;
    }
}
 
class Coffee extends CaffeineBeverage {
 
    /**
     * 模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤
     *
     */
    @Override
    void boilWater() {
        System.out.println("Boiling water  long long");
    }
 
    @Override
    void brew() {
        System.out.println("Dripping coffee through filter");
    }
 
    @Override
    void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }
 
    /**
     * 有了钩子,我能够决定要不要覆盖方法。如果我不提供在自己 的方法,抽象类会提供一个默认的实现
     */
    @Override
    boolean needCondiments() {
        return false;
    }
 
}
 
class Tea extends CaffeineBeverage {
 
    @Override
    void brew() {
        System.out.println("steeping the tea");
    }
 
    @Override
    void addCondiments() {
        System.out.println("Adding lemon");
    }
}


  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 53
博文 171
码字总数 133499
×
不正经啊不正经
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: