设计模式笔记08-模板方法模式
1 引言
直到目前,我们的议题都绕着封装转,我们已经封装了对象创建、方法调用、复杂接口、鸭子、披萨。接下来呢?我们将要深入封装算法块,好让子类可以在任何时候都可以将自己挂接进运算里。我们甚至会在本章学到一个受到好莱坞影响而启发的设计原则。
2 正文
2.1 多来点咖啡因吧
有些人没有咖啡就活不下去,有些人则离不开茶。两者的共同成分是什么,当然是咖啡因啦。
让我们扮演“代码师傅“,写一些代码来创建咖啡和茶。
下面是咖啡:
public class Coffee {
/*
* 这是我们的咖啡冲泡方法,直接取自训练手册。
* 每个步骤都被实现在分离的方法中。
* 这里每个方法都实现了算法中的一个步骤:煮沸水、冲泡咖啡、把咖啡倒进杯子、加糖和加奶。
*/
void prepareRecipe() {
boilWater();
brewCoffeeGrinds();
pourInCup();
addSugarAndMilk();
}
public void boilWater() {
System.out.println("Boiling water");
}
public void brewCoffeeGrinds() {
System.out.println("Dripping Coffee through filter");
}
public void pourInCup() {
System.out.println("Pouring into cup");
}
public void addSugarAndMilk() {
System.out.println("Adding Sugar and Milk");
}
}
下面是茶
public class Tea {
/*
* 这看起来和前一页的咖啡的实现很像,其中第2和第4个步骤不一样,但基本上是相同的冲泡法。
*/
void prepareRecipe() {
boilWater();
steepTeaBag();
pourInCup();
addLemon();
}
public void boilWater() {
System.out.println("Boiling water");
}
public void steepTeaBag() {
System.out.println("Steeping the tea");
}
public void addLemon() {
System.out.println("Adding Lemon");
}
public void pourInCup() {
System.out.println("Pouring into cup");
}
}
我们发现了重复的代码,这是好现象。这表示我们需要清理一下设计了。在这里,既然茶和咖啡是如此的相似,似乎我们应该将共同的部分抽出来,放进一个基类中。
现在我们有了新的prepareRecipe()方法,但是需要让它能够符合代码。要想这么做,我们先从CaffeineBeverage(咖啡因饮料:茶和咖啡)超类开始。
public abstract class CaffeineBeverage {
/*
* 现在,用同一个prepareRecipe()方法来处理茶和咖啡。
* prepareRecipe()被声明为final,因为我们不希望子类覆盖这个方法。
* 我们将步骤2和步骤4泛化为brew()和addCondiments()方法。
*/
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");
}
}
最后,我们需要处理咖啡和茶类了。这两个类现在都是依赖超类(咖啡因饮料)来处理冲泡法,所以只需要自行处理冲泡和添加调料部分。
2.2 认识模板方法
prepareRecipe()是我们的模板方法。为什么?
因为:
1、毕竟它是一个方法。
2、它用作一个算法的模板,在这个例子中,算法是用来制作咖啡因饮料的。
在这个模板中,算法内的每一个步骤都被一个方法代表了。某些方法是由这个类(超类)来处理的,某些方法则是由子类来处理。
模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
2.3 对模板方法进行挂钩
钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩。要不要挂钩,由子类自行决定。
钩子有好几种用途,让我们先看其中一个,稍后再看其他几个:
public abstract class CaffeineBeverageWithHook {
/*
* 我们加上了一个小小的条件语句,而该条件是否成立,是由一个具体方法customerWantsCondiments()决定的。
* 如果顾客“想要”调料,只有这时我们才调用addCondiments()。
*/
void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("Boiling water");
}
void pourInCup() {
System.out.println("Pouring into cup");
}
/*
* 我们再这里定义了一个方法,(通常)是空的缺省实现。这个方法只会返回true,不做别的事情。
* 这就是钩子,子类可以覆盖这个方法,但不见得一定要这么做。
*/
boolean customerWantsCondiments() {
return true;
}
}
2.4 好莱坞原则
好莱坞原则:别调用(打电话给)我们,我们会调用(打电话给)你。
好莱坞原则可以给我们一种防止“依赖“的方法。当高层组件依赖低层组件,而低层组件又依赖高层组件,而高层组件又依赖边侧组件,依赖就发生了。在这种情况下,没有人可以轻易地搞定系统是如何设计的。
在好莱坞原则之下,我们允许低层组件讲自己挂钩到系统上,但是高层组件决定什么时候和怎么样使用这些低层组件。换句话说,高层组件对待低层组件的方式是”别调用我们,我们会调用你“。
2.5 用模板方法来排序
实现compareTo()方法即可。
3 本章小结
模板方法从字面意思就很好理解,把握住新学的好莱坞原则,避免依赖,这个就是本章的精髓。
分享到:
相关推荐
《HeadFirst设计模式学习笔记1--策略模式Demo》 在软件工程中,设计模式是一种解决常见问题的标准方案,它提供了一种在特定情况下组织代码的模板。策略模式是设计模式中的一种行为模式,它允许在运行时选择算法或...
在软件开发领域,设计模式是经验丰富的开发者们总结出的解决常见问题的模板或最佳实践。Java设计模式是Java程序员提升代码质量和可维护性的重要工具。这个“Java版设计模式学习笔记”涵盖了多种设计模式,旨在帮助...
设计模式是软件工程中的一种重要概念,它代表了在特定情境下解决问题的...设计模式笔记中的内容应该涵盖了以上所述的各种模式,通过深入学习和实践,你可以将这些模式应用到实际项目中,提升自己的编程技能和设计能力。
在《23个设计模式图解--学习笔记》中,我们探讨了这些模式,以便于理解和应用到实际开发中。以下是这23个设计模式的详细说明: 1. **工厂方法**(Factory Method):定义一个用于创建对象的接口,让子类决定实例化...
在IT行业中,设计模式是软件开发中的一种标准解决方案,它代表了在特定上下文中解决常见问题的最佳实践。这里我们关注的是一个名为"pattern.zip"的压缩包文件,它包含了23种经典的设计模式,这些模式在实践中被广泛...
这份"根据《JAVA与设计模式》整理的笔记及示例代码"涵盖了Java语言和设计模式的核心概念,旨在帮助开发者理解和应用这些模式。 一、设计模式的基本概念 设计模式是对在特定情境下软件设计问题的解决方案的一种描述...
C++设计模式笔记(03-02) – Template Method_模板方法(下): https://blog.csdn.net/mofan6930/article/details/104383750 参考书籍:《设计模式:可复用面向对象软件的基础》 参考课程:《C++设计模式》-李建忠 ...
以上只是设计模式笔记中的一部分内容,实际上每个模式都有其特定的适用场景和优缺点。理解并熟练运用这些模式,可以提高代码的可读性、可维护性和复用性,降低系统复杂度,提升软件设计的质量。在实际项目中,应根据...
设计模式可以被归类为创建型、结构型和行为型三类,每类包含若干种模式,如创建型中的工厂方法模式、抽象工厂模式、单例模式、建造者模式和原型模式;结构型中的适配器模式、装饰器模式、代理模式、外观模式、桥接...
创建型设计模式关注的是对象的创建,如工厂方法、抽象工厂、建造者、原型和单例模式,它们分别处理不同程度的对象创建延迟和实例化过程。结构型模式则涉及如何组合类和对象,包括适配器、桥接、组合、装饰器、外观、...
设计模式是一种在软件设计中被广泛认可的解决特定问题的模板,它代表了最佳实践,是经验丰富的开发者在面临相似问题时的一种通用解决方案。《新版设计模式手册》是一本深入探讨设计模式的书籍,旨在帮助程序员更好地...
在这个“设计模式之美”的学习笔记中,我们将探讨一些主要的设计模式,以及它们在实际开发中的应用。 首先,我们从创建型模式开始。这类模式主要用于对象的创建,如单例模式(Singleton)、工厂模式(Factory ...
设计模式Golang实现《研磨设计模式》读书笔记Go语言设计模式Go语言设计模式的实例代码创建模式工厂简单模式(Simple Factory)工厂方法模式(工厂方法)抽象工厂模式(Abstract Factory)创建者模式(Builder)原型...
设计模式是软件工程中的一种最佳实践,它是在特定上下文中解决常见问题的模板。这个压缩包文件包含了23种设计模式的学习笔记和源码,旨在帮助开发者深入理解并熟练运用这些模式。以下是对每种设计模式的详细解释,...
### 设计模式笔记总结 本篇文章是对一份设计模式学习资料的深入解读,这份资料包含了19种经典的设计模式,并提供了C#示例代码,适用于学习和复习。下面将逐一介绍这些设计模式及其核心概念。 #### 1. 简单工厂模式...
这份由台湾作者编写的笔记,结合Java语言,为读者提供了一种深入理解并应用设计模式的方式。以下是对这些设计模式的详细解释: 1. **创建型模式(Creational Patterns)** 创建型模式关注于对象的创建过程,它们帮助...
设计模式是软件开发中经常使用的一种通用解决方案模板,用于解决特定上下文中的常见问题。它们源于设计模式的研究,通常被认为是软件设计中的最佳实践。 首先,学习方法要正确。理解模式的意图,即它的目的是什么,...
本资料“图解Java设计模式笔记总结word版本”聚焦于通过图文并茂的方式,深入浅出地解析各种设计模式。以下是基于这个主题的详细知识点讲解: 1. **设计模式的分类** - **创建型模式**:如单例(Singleton)、工厂...
这个压缩包中的“设计模式笔记”涵盖了所有23种GOF(GoF,Gamma, Helm, Johnson, Vlissides四位作者)经典设计模式,这些模式是面向对象设计的核心组成部分,对于提升代码的可读性、可维护性和可扩展性具有重要意义...
总的来说,STM32工作笔记0020的内容涵盖了基于寄存器的新建工程模板方法,以及跑马灯应用的实现,旨在帮助开发者深入理解STM32的底层操作,提高嵌入式编程能力。通过实践和学习,开发者能够更好地驾驭STM32微控制器...