设计模式之模板方法模式--慕课网笔记

第1章 模板方法模式初探
1-1 什么是模板方法模式

模板方法模式Template Method
1. 什么是模板方法模式
2. 如何实现模板方法模式
3. 模板方法模式的特点
4. 模板方法模式在项目中的应用

生活中的模板
1. 进门取号
2. 填写单据
3. 等待叫号
4. 窗口办理

奥运会开幕式
1. 升国旗奏国歌
2. 致辞讲话
3. 文艺汇演
4. 入场仪式
5. 点燃奥运圣火

算法执行的统一框架
- Step 1
- Step 2
- …
- Step n

饮料的调制方法
- 咖啡的泡法
1. 把水煮沸
2. 用沸水冲泡咖啡
3. 把咖啡倒进杯子
4. 加糖和牛奶
- 茶的泡法
1. 把水煮沸
2. 用沸水浸泡茶叶
3. 把茶倒进杯子
4. 加柠檬

提神饮料泡法
1. 把水煮沸(boilWater)
2. 泡饮料(brew)
3. 把饮料倒进杯子(pourInCup)
4. 加调味料(addCondiments)

第2章 模板方法模式的代码实现
2-1 用抽象基类定义框架
/*
 * 抽象基类,为所有子类提供一个算法框架
 * 
 * 提神饮料
 */
public abstract class RefreshBeverage {

    /*
     * 制备饮料的模板方法
     * 封装了所有子类共同遵循的算法框架
     */
    public final void prepareBeverageTemplate(){
        //步骤1 将水煮沸
        boilWater();
        //步骤2 泡制饮料
        brew();
        //步骤3 将饮料倒入杯中
        pourInCup();
        //步骤4 加入调味料
        addCondiments();
    }


    /*
     * 基本方法,将水煮沸
     */
    private void boilWater() {
        System.out.println("将水煮沸");
    }

    /*
     * 基本方法,将饮料倒入杯中
     */
    private void pourInCup() {
        System.out.println("将饮料倒入杯中");
    }

    /*
     * 抽象的基本方法,泡制饮料
     */
    protected abstract void brew();


    /*
     * 抽象的基本方法, 加入调味料
     */
    protected abstract void addCondiments();


}
2-2 具体子类实现延迟步骤
/*
 * 具体子类,提供了咖啡制备的具体实现
 */
public class Coffee extends RefreshBeverage {

    @Override
    protected void brew() {
        System.out.println("用沸水冲泡咖啡");

    }

    @Override
    protected void addCondiments() {
        System.out.println("加入糖和牛奶");
    }

}
/*
 * 具体子类,提供了制备茶的具体实现
 */
public class Tea extends RefreshBeverage {

    @Override
    protected void brew() {
        System.out.println("用80度的热水浸泡茶叶5分钟");
    }

    @Override
    protected void addCondiments() {
        System.out.println("加入柠檬");
    }


}
public class RefreshBeverageTest {

    public static void main(String[] args) {

        System.out.println("制备咖啡...");
        RefreshBeverage b1 = new Coffee();
        b1.prepareBeverageTemplate();
        System.out.println("咖啡好了!");

        System.out.println("\n******************************************");

        System.out.println("制备茶...");
        RefreshBeverage b2 = new Tea();
        b2.prepareBeverageTemplate();
        System.out.println("茶好了!");

    }

}
2-3 钩子使子类更灵活
/*
 * 抽象基类,为所有子类提供一个算法框架
 * 
 * 提神饮料
 */
public abstract class RefreshBeverage {

    /*
     * 制备饮料的模板方法
     * 封装了所有子类共同遵循的算法框架
     */
    public final void prepareBeverageTemplate(){
        //步骤1 将水煮沸
        boilWater();
        //步骤2 泡制饮料
        brew();
        //步骤3 将饮料倒入杯中
        pourInCup();
        if(isCustomerWantsCondiments()){
            //步骤4 加入调味料
            addCondiments();
        }
    }

    /*
     * Hook, 钩子函数,提供一个默认或空的实现
     * 具体的子类可以自行决定是否挂钩以及如何挂钩
     * 询问用户是否加入调料
     */
     protected boolean isCustomerWantsCondiments() {
        return true;
    }

    /*
     * 基本方法,将水煮沸
     */
    private void boilWater() {
        System.out.println("将水煮沸");
    }

    /*
     * 基本方法,将饮料倒入杯中
     */
    private void pourInCup() {
        System.out.println("将饮料倒入杯中");
    }

    /*
     * 抽象的基本方法,泡制饮料
     */
    protected abstract void brew();


    /*
     * 抽象的基本方法, 加入调味料
     */
    protected abstract void addCondiments();


}
/*
 * 具体子类,提供了咖啡制备的具体实现
 */
public class Coffee extends RefreshBeverage {

    @Override
    protected void brew() {
        System.out.println("用沸水冲泡咖啡");

    }

    @Override
    protected void addCondiments() {
        System.out.println("加入糖和牛奶");
    }

}
/*
 * 具体子类,提供了制备茶的具体实现
 */
public class Tea extends RefreshBeverage {

    @Override
    protected void brew() {
        System.out.println("用80度的热水浸泡茶叶5分钟");
    }

    @Override
    protected void addCondiments() {
        System.out.println("加入柠檬");
    }

    @Override
    /*
     * 子类通过覆盖的形式选择挂载钩子函数
     * @see com.imooc.pattern.template.RefreshBeverage#isCustomerWantsCondiments()
     */
    protected boolean isCustomerWantsCondiments(){
        return false;
    }

}
public class RefreshBeverageTest {

    public static void main(String[] args) {

        System.out.println("制备咖啡...");
        RefreshBeverage b1 = new Coffee();
        b1.prepareBeverageTemplate();
        System.out.println("咖啡好了!");

        System.out.println("\n******************************************");

        System.out.println("制备茶...");
        RefreshBeverage b2 = new Tea();
        b2.prepareBeverageTemplate();
        System.out.println("茶好了!");

    }

}
第3章 模板方法模式总结
3-1 模板方法模式总结

抽象基类
1. 基本方法
2. 抽象方法
3. 可选钩子
4. Template方法(final)

好莱坞原则
Don’t call us!We will call you.

具体子类
1. 实现基类中的抽象方法
2. 覆盖钩子方法

模板方法模式的实现要素
准备一个抽象类,将部分逻辑以具体方法的形式实现,然后
声明一些抽象方法交由子类实现剩余逻辑,用钩子方法给予
子类更大的灵活性。最后将方法汇总构成一个不可改变的
模板方法。

模板方法模式的适用场景
1. 算法或操作遵循相似的逻辑
2. 重构时(把相同的方法抽取到父类中)
3. 重要、复杂的算法,核心算法设计为模板算法

模板方法模式的优点
1. 封装性好
2. 复用性好
3. 屏蔽细节
4. 便于维护

模板方法模式的缺点
继承

3-2 行业案例分享

运营商日志

  • 种类繁多数量巨大的日志
  • 抽取共性
  • 获得规律

    1. 获得文件
    2. 打开文件
    3. 读取日志结构
    4. 处理单行日志
    5. 清理工作

扩展点
- beforeProcessOneFile()
- afterProcessOneFile()


《模式的秘密—模板方法模式》视频地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值