【设计模式】《Head First 设计模式》读书笔记——模板方法模式

模板方法模式:

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

涉及设计原则:

1.好莱坞原则:别调用我们,我们会调用你
2.为交互对象之间的松耦合设计而努力

问题简单描述:

创建咖啡和茶的步骤很类似,把水煮沸->冲泡->倒进杯子->加配料,其中第一步第三步是同样的方法,冲泡和加配料具体操作不同。有没有一种方法减少代码的重复性,又可以保留两者的不同。

解决思路:

创建一个父类,将相同的方法实现,不同的方法定义为抽象方法,并提供一个规定了制作步骤的模板方法。茶跟咖啡都继承这个父类,实现其中的抽象方法,调用者只需调用模板方法完成制作。

UML图:




实现代码:

模板方法基类

package templateMethod;

/**
 * 咖啡因饮料基类(包含规定了算法结构的模板方法)
 * @author terry
 *
 */
public abstract class CoffeineBeverage {
	
	//模板方法,规定了算法结构,子类不得改变
	final void prepareRecipe(){
		boilWater();
		brew();
		pourInCup();
		addCondiments();
	}
	
	//冲泡(不同子类实现方法不同)
	abstract void brew();
	
	//加配料(钩子)
	void addCondiments(){
		//默认不加配料,在子类中可以改变
		System.out.println("add no condiments");
	}
	
	//烧水(任何子类都同样的方法)
	final void boilWater(){
		System.out.println("Boiling water");
	}
	
	//倒进杯子(任何子类都相同的方法)
	final void pourInCup(){
		System.out.println("Pouring into Cup");
	}
}

实现类

package templateMethod;

/**
 * 茶子类(继承模板方法基类)
 * @author terry
 *
 */
public class Tea extends CoffeineBeverage{

	@Override
	void brew() {
		//子类实现抽象方法
		System.out.println("Steepint the tea");
	}
	
	void addCondiments(){
		//子类可以覆盖钩子方法
		System.out.println("add some lemon");
	}
}
package templateMethod;

/**
 * 咖啡子类(继承模板方法基类)
 * @author terry
 *
 */
public class Coffee extends CoffeineBeverage{

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

}

测试类

package templateMethod;

public class Test {
	public static void main(String[] args){
		Tea tea=new Tea();
		Coffee coffee=new Coffee();
		System.out.println("Making tea……");
		tea.prepareRecipe();
		System.out.println("Making coffee……");
		coffee.prepareRecipe();
	}

}

运行结果



模板方法模式利用了继承提高了代码的复用性,利用抽象方法保留子类的特点,模板方法规定了算法的步骤。在模板方法基类中有三种方法:抽象方法、具体方法、钩子方法。抽象方法由子类实现,用于不同子类实现不同的方法。具体方法加final修饰符不让子类修改,用于不同子类实现一定相同的方法。钩子方法在基类中实现但不加final修饰符,一般做默认实现或者空实现,用于不同子类实现可能不同的方法。调用者调用的模板方法来自基类,而模板方法中存在的抽象方法的实现在子类中,这就是所谓的好莱坞原则中的我来调用你,达到了调用者跟具体抽象方法的解耦。如果抽象方法的实现也存在很多子类实现相同的情况,觉得可以再加策略模式组合。该统一的统一(final),需要特色的抽象。

欢迎批评指正 ^ ^


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值