面向对象设计模式:行为型模式之模板方法模式

一、模板方法引入:泡茶与冲咖啡

  • 泡茶

    • 烧水
    • 泡茶
    • 倒入杯子
    • 加入柠檬
  • 冲咖啡

    • 烧水
    • 冲咖啡
    • 倒入杯子
    • 加入牛奶和糖

在这里插入图片描述

二、模板方法,TemplateMethod

2.1 Intent 意图
  • Define the skeleton of an algorithm in an operation, deferring some steps to lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure. 在操作中定义算法的骨架,延迟一些步骤,让子类在不改变算法结构的情况下重新定义算法的某些步骤。

  • “Hook”: Control subclasses extensions(“钩子”:控制子类扩展)

    • You can define a template method that calls “hook” operations at specific points, thereby permitting extensions only at those points. 可以定义一个在特定点上调用“钩子”操作的模板方法,并只允许在这些点上进行扩展。
2.2 Applicability 适用性
  • To implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary. 一次实现算法的不变部分,并将其留给子类来实现可能发生变化的行为.
  • When common behavior among subclasses should be factored and localized in a common class to avoid code duplication. 当子类之间的公共行为应该在一个公共类中被分解和本地化,以避免代码重复时.
  • Control subclasses extensions.
2.3 类图

在这里插入图片描述

2.4 模板方法类实现要点
  • 模板方法类为抽象类
  • 模板方法 final 修饰
  • 最小化原始操作:抽象方法与公用方法
    • An important goal in designing template methods is to minimize the number of primitive operations that a subclass must override to flesh out the algorithm. 设计模板方法的一个重要目标是最小化子类必须覆盖的原始操作的数量
2.5 应用实例
2.5.1 JDK Map
  • Map 模板方法
    在这里插入图片描述
    get、put 在 Map 接口均未实现
    在这里插入图片描述
  • HashMap 模板方法
    在这里插入图片描述
    afterNodeAccess 在 HashMap 里的方法体为空方法体:
    在这里插入图片描述
    afterNodeAccess 在 LinkedHashMap 里被重写(replace 方法未被重写)
    在这里插入图片描述
2.5.2 HttpServlet

HttpServlet in JavaEE:service()

2.6 泡茶与冲咖啡
  • 饮品类
public abstract class Beverage {
    final void prepareBeverage() {
        boilWater();
        brew();
        pourInCup();
        if (wantCondiments()) {
            addCondiments();
        }
    }

    // Hock:冲泡
    abstract void brew();

    // Hock:加入调味品
    abstract void addCondiments();

    private void boilWater() {
        System.out.println("Begin boil water! ...... Done!");
    }

    private void pourInCup() {
        System.out.println("Pour in cup!");
    }

    // Hook:默认需要调味品,子类可重写
    boolean wantCondiments() {
        return true;
    }
}

  • 咖啡
public class CoffeeBeverage extends Beverage {
    @Override
    protected void brew() {
        System.out.println("Brew coffee!");
    }

    @Override
    protected void addCondiments() {
        System.out.println("Add milk and sugar to coffee!");
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class TeaBeverage extends Beverage {
    @Override
    protected void brew() {
        System.out.println("Brew tea!");
    }

    @Override
    protected void addCondiments() {
        System.out.println("Add lemon to tea");
    }

    @Override
    boolean wantCondiments() {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));

        System.out.println("Would you like to add lemon to tea? Please Enter yes or no(default no)!");
        String ans = null;
        try {
            ans = bf.readLine();
        } catch (IOException e) {
            System.out.println("Error input!");
        }
        if (ans == null || "no".equalsIgnoreCase(ans)) {
            return false;
        }
        return "yes".equalsIgnoreCase(ans);
    }
}

  • Demo for test
public class TemplateDemo {
    public static void main(String[] args) {
        Beverage coffee = new CoffeeBeverage();
        coffee.prepareBeverage();
        System.out.println("\n");
        Beverage tea = new TeaBeverage();
        tea.prepareBeverage();
    }
}

  • Output
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值