设计模式之模板方法

一、定义

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

二、核心思想

1、这个模式是用来创建一个算法的模板

2、模板方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现

3、确保算法的结构保持不变,同时由子类提供部分实现

三、相关设计原则

好莱坞原则

1、别调用(打电话给)我们,我们会调用(打电话给)你

2、用于防止依赖腐败

3、要不要用你,高层组件说了算

4、好莱坞原则让底层组件被挂钩进计算中,而又不会让高层组件依赖底层组件 

钩子

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

2、有了钩子,我们可以让模板方法中的程序决定是否调用模板方法中的某些方法


四、使用场景

1、茶和咖啡的冲泡方式

茶:(1)把谁煮沸(2)用沸水冲泡咖啡(3)把咖啡倒进杯子(4)加糖和牛奶

咖啡:(1)把谁煮沸(2)用沸水浸泡茶叶(3)把茶倒进杯子(4)加柠檬

2、观察场景

两种冲泡方式有相同的地方,也有不同的地方


五、代码实现

package com.fengshu.limanman;

/**
 * 
 * 1、理解模板方法 2、理解好莱坞原则 3、理解钩子的用法
 * 
 * @author 李慢慢
 *
 */
public class Temple {
	public static void main(String[] args) {
		CaffeineBeverage caffeineBeverage = new Coffee();
		caffeineBeverage.pripareRecipe();
	}
}

/**
 * 制作咖啡因饮料的模板方法
 *
 */
abstract class CaffeineBeverage {

	/**
	 * final 确保算法的结构保持不变,也体现了好莱坞设计原则,让子类没办法直接调用父类(高层组件方法),只能由高层组件来调用子类实现的方法
	 */
	final void pripareRecipe() {
		boilWater();
		brew();
		pourInCup();
		// 钩子决定子类是否执行模板中的某些方法
		if (needCondiments()) {
			addCondiments();
		}
	}

	/**
	 * 模板方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现
	 */
	abstract void brew();

	/**
	 * 模板方法将一部分的实现延迟到了子类中
	 */
	abstract void addCondiments();

	void boilWater() {
		System.out.println("Boiling water");
	}

	void pourInCup() {
		System.out.println("Pouring into cup");
	}

	/**
	 * 使用了钩子默认true,由子类决定是否进行覆盖
	 * 
	 * @return
	 */
	boolean needCondiments() {
		return true;
	}
}

class Coffee extends CaffeineBeverage {

	/**
	 * 模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤
	 *
	 */
	@Override
	void boilWater() {
		System.out.println("Boiling water  long long");
	}

	@Override
	void brew() {
		System.out.println("Dripping coffee through filter");
	}

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

	/**
	 * 有了钩子,我能够决定要不要覆盖方法。如果我不提供在自己 的方法,抽象类会提供一个默认的实现
	 */
	@Override
	boolean needCondiments() {
		return false;
	}

}

class Tea extends CaffeineBeverage {

	@Override
	void brew() {
		System.out.println("steeping the tea");
	}

	@Override
	void addCondiments() {
		System.out.println("Adding lemon");
	}
}



六、参考

《Head First 设计模式》

转载于:https://my.oschina.net/fengshuzi/blog/370485

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值