《Head First 设计模式》学习笔记——模板方法模式

模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。

设计模式

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

模板就是一个方法,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现。这样可以确保算法的结构保持不变,同时由子类提供部分实现。

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

使用钩子的真正目的:

钩子可以让子类实现算法中可选的部分,或者在钩子对于子类的实现并不重要的时候,子类可以对此钩子置之不理。钩子的另一个用法,是让子类能够有机会对模板方法中某些即将发生的(或刚刚发生的)步骤做出反应。

设计原则

好莱坞原则:别调用我们,我们会调用你。

在好莱坞原则下,我们允许低层组件将自己挂钩到系统之上,但是高层组件会决定什么时候和怎样使用这些低层组件。换句话说,高层组件对低层组件的方式是“别调用我们,我们会调用你”。

要点

“模板方法”定义了算法的步骤,把这些步骤的实现延迟到子类中。

模板方法模式为我们提供了一种代码复用的重要技巧。

模板方法的抽象类可以定义具体方法、抽象方法、钩子。

为了防止子类改变模板方法中的算法,我们可以将模板方法声明为final。

策略模式和模板方法模式都是封装算法,前者是使用组合,后者是使用继承。

工厂方法是模板方式的一种特殊版本。

典型的摸板方法应用

1. HttpServlet技术

2. Swing的窗口程序

3. Applet

模板方法模式:

//声明为抽象类,子类必须实现其操作
public abstract class CaffeineBeverage
{

	//声明为final,不希望子类覆盖这个方法
	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");
	}
}

//extends继承
public class Tea extends CaffeineBeverage {
	//需要定义抽象方法
	public void brew() {
		System.out.println("Steeping the tea");
	}
	public void addCondiments() {
		System.out.println("Adding Lemon");
	}
}

使用钩子:

public abstract class CaffeineBeverageWithHook {

	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");
	}

	//定义了一个缺省实现,子类可以覆盖它,但不见得一定要这么做
	boolean customerWantsCondiments() {
		return true;
	}
}

public class CoffeeWithHook extends CaffeineBeverageWithHook {

	public void brew() {
		System.out.println("Dripping Coffee through filter");
	}

	public void addCondiments() {
		System.out.println("Adding Sugar and Milk");
	}

	//覆盖了这个方法,提供了自己的功能
	public boolean customerWantsCondiments() {

		//让用户输入对调料的决定
		String answer = getUserInput();

		if (answer.toLowerCase().startsWith("y")) {
			return true;
		} else {
			return false;
		}
	}

	private String getUserInput() {
		String answer = null;

		System.out.print("Would you like milk and sugar with your coffee (y/n)? ");

		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		try {
			answer = in.readLine();
		} catch (IOException ioe) {
			System.err.println("IO error trying to read your answer");
		}
		if (answer == null) {
			return "no";
		}
		return answer;
	}
}

《Head First 设计模式》学习笔记——模板方法模式,布布扣,bubuko.com

时间: 2024-12-12 05:33:36

《Head First 设计模式》学习笔记——模板方法模式的相关文章

设计模式学习之模板方法模式(TemplateMethod,行为型模式)(9)

一.什么是模板方法模式 Template Method模式也叫模板方法模式,是行为模式之一,它把具有特定步骤算法中的某些必要的处理委让给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为. 二.模板方法模式的应用场景 Template Method模式一般应用在具有以下条件的应用中: - 具有统一的操作步骤或操作过程 - 具有不同的操作细节 - 存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同 private static void Main(string[] arg

设计模式学习笔记--外观模式

好久没写设计模式的blog了,这次重新回来填坑,先找一个最简单但是却最常用的设计模式来学习,外观模式.其实说是一个设计模式,其实我们在实际的编程中无时无刻不在用外观模式,可以说这个设计模式已经渗透到编程的各个方便,可能我们自己没感觉出来罢了. 一.外观模式的定义 先来看一下外观模式的定义: 外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层的接口,这个接口使得这一系列子系统更加容易使用. 简单解释一下,所谓外观模式,就是在我们设计系统的时候,将若干个子系统的功

设计模式学习笔记-工厂模式

一.概述 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法(Factory Method)使一个类的实例化延迟到其子类: 2.模式中的角色 Product(Map):定义工厂方法所创建的对象的接口. ConcreteProduct(BaiduMap.GaodeMap):具体Product,实现Product接口. Creator(IMapFactory):声明工厂方法,该方法返回一个Product类型的对象. ConcreteCreator(BaiduMapFactory.Gaod

设计模式学习笔记-桥接模式

一.概述 将抽象部分与它的实现部分分离,使它们都可以独立地变化. 二.模式中的角色 Abstraction:定义抽象类的接口:维护一个指向Implementor类型对象的指针: RefinedAbstraction:扩充由Abstraction定义的接口: Implementor:定义具体行为,具体特征的应用接口: ConcreteImplementor:实现Implementor. 三.UML类图 四.代码实现 4.1 桥接模式的实现代码 /// <summary> /// 实现 /// &

设计模式学习笔记-建造者模式

一.概述 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示: 二.模式中的角色 Builder:为创建一个Product对象的各个部件指定抽象接口: ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件:定义并明确它所创建的表示:提供一个检索产品的接口: Director:构造一个使用Builder接口的对象: Product:表示被构造的复杂对象,ConcreteBuilder创建该产品的内部表示并定义它的装配过程:包含定义组成部件的类,

设计模式学习笔记--策略模式

定义: 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 我们在使用一些功能时,有时有很多种实现方法,或者多种结果,但是都有同样的使用方法,即调用接口,这就是策略模式. 例子: // 设计模式Demo.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #include <string> using namespa

Java-马士兵设计模式学习笔记-命令模式

一.概述 命令模式 二.代码 1.Client.java 1 public class Client { 2 3 public void request(Server server){ 4 server.addCommand(new TextCommand()); 5 server.addCommand(new ImageCommand()); 6 server.doSomething(); 7 } 8 } 2.Server.java 1 public class Server { 2 3 pr

设计模式学习笔记——组合模式

组合模式 组合模式,将对象组合合成树形结构以表示"部分-整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. 代码实现 接口声明Component /** * 接口声明 * @author xukai 2016年3月26日 下午4:58:37 * */ public abstract class Component { protected String name; public Component(String name) { this.name = name; }

Java-马士兵设计模式学习笔记-桥接模式

一.概述 1.桥接模式的应用情况:(1)两个维度扩展(2)排列组合 二.代码 1.Gift.java 1 public class Gift { 2 3 protected GiftImpl giftImpl; 4 } 2.GiftImpl.java 1 public class GiftImpl { 2 3 } 3.WarmGift.java 1 public class WarmGift extends Gift { 2 3 public WarmGift(GiftImpl giftImpl