设计模式总结之模版方法模式 (Template)

模式定义

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

模式理解

        简单来说就是,模版中定好步骤并实现基本方法,子类实现特定方法。

        需要注意的地方:模版方法需要使用final标记以防止其它方法对模版做改动,模版方法的基本实现需要标记为private使得其子类不能修改模版类的最基本实现,模版方法中可拓展实现需标记为抽象的并且为protected。使得只有子类才能实现其可变方法。

模式例子

        以冲泡咖啡或茶为例,实现模版方法。

        泡咖啡步骤:把水煮沸,冲泡,把饮料倒进杯子,加调料。

        泡茶步骤:把水煮沸,用沸水浸泡茶叶,把茶倒进杯子。

    模版抽象类(RefreshBeverage.java)

package com.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();
	
	
}

    咖啡类(Coffee.java)

 package com.imooc.pattern.template;

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

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

	}

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

}

    茶类(Tea.java)

 package com.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;
	}
	
}

    测试类(RefreshBeverageTest.java)

package com.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("茶好了!");

	}

}

模式适用场景

        算法或操作遵循相同的逻辑;

        重构中提取相同功能代码做成模版;

        重要或复杂的代码。

模式优缺点

       优点:封装性好,复用性好,屏蔽细节,便于维护。

       缺点:继承,已经有继承的类不好做模版方法的重构。

猜你喜欢

转载自408599764.iteye.com/blog/2290049