《Head-First-设计模式》笔记11-模板方法模式
定义
模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
类图
实例
咖啡和茶的冲泡步骤都差不多,可以理解为两份冲泡法都采用了基本相同的算法:
- 煮沸水。
- 用热水泡茶或咖啡。
- 把饮料倒进杯子。
- 加入适当调料(奶、糖或者柠檬片)。
创建咖啡因饮料抽象类
public abstract class CaffeineBeverage {
final void prepareRecipe() { // 不希望子类覆盖这个方法
boilWater();
brew();
pourInCup();
addCondiments();
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("Boiling water");
}
void pourInCup() {
System.out.println("Pouring into cup");
}
}
创建具体饮料(子类)
public class Tea extends CaffeineBeverage {
@Override
void brew() {
System.out.println("tea");
}
@Override
void addCondiments() {
System.out.println("Adding lemon");
}
}
public class Coffee extends CaffeineBeverage {
@Override
void brew() {
System.out.println("coffee");
}
@Override
void addCondiments() {
System.out.println("Adding Sugar and Milk");
}
}
测试
public class CaffeineTest {
public static void main(String[] args) {
Tea tea = new Tea();
tea.prepareRecipe();
Coffee coffee = new Coffee();
coffee.prepareRecipe();
}
}
对模版方法进行挂钩
钩子是一种被声明在抽象类中的方法,但是只有空的或者默认的实现。
在 CaffeineBeverage 抽象类中加入 customerWantsCondiments() 方法,用来判断顾客是否想要加入调料,然后就可以在 prepareRecipe() 方法中进行判断。
final void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
boolean customerWantsCondiments(){
return true;
}
然后在 Coffee 类中覆盖该方法。
@Override
public boolean customerWantsCondiments() { //调用钩子
String answer = getUserInput();
if (answer.toLowerCase().startsWith("y")) {
return true;
} else {
return false;
}
}
Java 中数组排序
由被排序的对象内的每个元素自行提供比较大小的算法部分,所以这虽然不是教科书上的模板方法,但它的实现仍然符合模板方法模式的精神。
模板方法模式和工厂方法的对比
在看模板方法的时候,很容易想到工厂方法。因为他们都是让具体的实现放在子类中,但是工厂方法主要是生产出产品,然后去应用产品。模板方法是在于依赖子类中的步骤中的其中几个步骤,具体的步骤已经在基类中写好了。
工厂方法是模板方法的一种特殊版本。
模板方法模式和策略模式的对比
同样模板方法模式和策略模式都是封装算法。但是策略模式中的每个策略都是单独的一个类。可以随时去更改策略。模板方法模式虽然也是封装了算法,其实主要在于封装步骤,具体的实现是根据依靠各个子类。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 bin07280@qq.com
文章标题:《Head-First-设计模式》笔记11-模板方法模式
文章字数:690
本文作者:Bin
发布时间:2018-07-14, 15:43:30
最后更新:2019-08-06, 00:07:35
原始链接:http://coolview.github.io/2018/07/14/Head-First-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E3%80%8AHead-First-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8B%E7%AC%94%E8%AE%B011-%E6%A8%A1%E6%9D%BF%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。