模式设计的秘密之模板方法模式

前言:先说说实际生活中的例子吧,比如我们去银行办理业务,通常会经历一下几个步骤。(1)拿号;(2)填写业务单;(3)等待叫号;(4)去柜台办理自己的业务。步骤一和三对每个普通的银行客户来说都是差不多的,而步骤二和四会因为个体的不同而有所不同,比如有人去存钱,有人去取钱,有人去办卡或者是找回自己的银行卡密码等等。再举一个例子,在举办奥运会开模式的时候,基本上回经历如下几个步骤。(1)升国旗;(2)重要的人讲话;(3)主办国的文艺汇演;(4)运动员入场;(5)点燃奥运圣火;步骤一,二和四基本上都是每一届奥运会差不多的,二步骤三和五是最能够展现一个主办国的风采的。

一.什么是模板方法模式?

核心是大的逻辑已经定义好了,你要做的就是一些具体的实现而已。也就是说在基类中定义好了模板的步骤的逻辑实现,子类只需要写一些具体的实现即可。


二.模板方法模式的结构?

AbstractTemplate(抽象模板):定义了完整的框架后,方法的调用顺序通常已经确定,但是还是会定义一些抽象的方法让之类去实现。


ConcreteTemplete(具体模板实现类):实现抽象类中定义的抽象方法,实现具体的功能,组成一个完整的逻辑。

三.模板方法模式的代码实现(java)

package com.imooc.pattern.template;

/*
 * 抽象基类,为所有子类提供一个算法框架
 * 
 * 提神饮料
 */
public abstract class RefreshBeverage {

	/*
	 * 制备饮料的模板方法
	 * 封装了所有子类共同遵循的算法框架
	 */
	public final void prepareBeverageTemplate(){
		//步骤1 将水煮沸
		boilWater();
		//步骤2 泡制饮料
		brew();
		//步骤3 将饮料倒入杯中
		pourInCup();
		if(isCustomerWantsCondiments()){
			//步骤4 加入调味料
			addCondiments();
		}
	}

	/*
	 * Hook, 钩子函数,提供一个默认或空的实现
	 * 具体的子类可以自行决定是否挂钩以及如何挂钩
	 * 询问用户是否加入调料
	 */
	 protected boolean isCustomerWantsCondiments() {
		return true;
	}

	/*
	 * 基本方法,将水煮沸
	 */
	private void boilWater() {
		System.out.println("将水煮沸");
	}
	
	/*
	 * 基本方法,将饮料倒入杯中
	 */
	private void pourInCup() {
		System.out.println("将饮料倒入杯中");
	}
	
	/*
	 * 抽象的基本方法,泡制饮料
	 */
	protected abstract void brew();
	
	
	/*
	 * 抽象的基本方法, 加入调味料
	 */
	protected abstract void addCondiments();
	
	
}
 package com.imooc.pattern.template;

/*
 * 具体子类,提供了咖啡制备的具体实现
 */
public class Coffee extends RefreshBeverage {

	@Override
	protected void brew() {
		System.out.println("用沸水冲泡咖啡");

	}

	@Override
	protected void addCondiments() {
		System.out.println("加入糖和牛奶");
	}

}
 package com.imooc.pattern.template;

/*
 * 具体子类,提供了制备茶的具体实现
 */
public class Tea extends RefreshBeverage {

	@Override
	protected void brew() {
		System.out.println("用80度的热水浸泡茶叶5分钟");
	}

	@Override
	protected void addCondiments() {
		System.out.println("加入柠檬");
	}

	@Override
	/*
	 * 子类通过覆盖的形式选择挂载钩子函数
	 * @see com.imooc.pattern.template.RefreshBeverage#isCustomerWantsCondiments()
	 */
	protected boolean isCustomerWantsCondiments(){
		return false;
	}
	
}

package com.imooc.pattern.template;

public class RefreshBeverageTest {

	public static void main(String[] args) {
		
		System.out.println("制备咖啡...");
		RefreshBeverage b1 = new Coffee();
		b1.prepareBeverageTemplate();
		System.out.println("咖啡好了!");
		
		System.out.println("\n******************************************");
		
		System.out.println("制备茶...");
		RefreshBeverage b2 = new Tea();
		b2.prepareBeverageTemplate();
		System.out.println("茶好了!");

	}

}

四.模板方法的优缺点?

优点:(1)封装性好,屏蔽很多细节;(2)复用性高;(3)便于维护。

缺点:因为它实现的机制是子类继承一个抽象类,而java只支持单继承,对于一些问题就会有局限性!

四.模板方法模式的应用场景?

在我们实际开发中的系统中,用到的框架很多都是用到了设计模式,我们只需要配置一下,写写核心的业务代码就可以了,很多事情框架都帮我们做了,框架在调用的过程中很多就用到了模板方法的设计模式。比如Spring MVC中的抽象类AbstractHandlerMapping,AbstractView等等。还有我们对各种日志的处理,也可以用模板设计模式来抽象提取,对文件的操作等等.....



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值