模板方法模式(Template Method Pattern)

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

例如:准备一杯咖啡与准备一杯柠檬茶有很多相同步骤:

准备咖啡:烧水- 冲泡咖啡 - 倒入杯中 - 加糖

准备柠檬茶:烧水- 冲泡茶 - 倒入杯中 - 加柠檬


public class Coffee {
	public void boilWater(){};
	
	public void makeCoffee(){};
	
	public void pourInCup(){};
	
	public void addSugar(){};
	
	public void prepareCoffee(){
		boilWater();
		makeCoffee();
		pourInCup();
		addSugar();
	};
}

通常的做法是抽象出一个共同的父类,将相同的步骤移至父类中:


public class Beverage {
	public void boilWater(){};
	
	public void pourInCup(){};
}
public class Coffee extends Beverage{
	public void makeCoffee(){};
	
	public void addSugar(){};
	
	public void prepareCoffee(){
		boilWater();
		makeCoffee();
		pourInCup();
		addSugar();
	};
}

简洁多了,但是仔细观察,冲泡咖啡与冲泡茶可以抽象为冲泡方法,加糖与加柠檬可以抽象为加配料方法:

public abstract class Beverage {
	public void boilWater(){};
	
	public abstract void make();
	
	public void pourInCup(){};
	
	public abstract void add();
}
public class Coffee extends Beverage{
	public void make(){
		System.out.println("make coffee");
	};
	
	public void add(){
		System.out.println("add sugar");
	};
	
	public void prepareCoffee(){
		boilWater();
		this.make();
		pourInCup();
		this.add();
	};
}

此时已经可以清楚的发现,prepareCoffee与prepareTea的步骤已经完全一样了,可抽象至共同父类Beverage中


public abstract class Beverage {
	public void boilWater(){};
	
	public abstract void make();
	
	public void pourInCup(){};
	
	public abstract void add();
	
	public void prepare(){
		boilWater();
		make();
		pourInCup();
		add();
	};
}
public class Coffee extends Beverage{
	public void make(){
		System.out.println("make coffee");
	};
	
	public void add(){
		System.out.println("add sugar");
	};
}

如果想要实现特定的准备咖啡流程,只需在Coffee类中重写Beverage的prepare方法即可

如果想要Beverage类所有子类的准备流程(必须严格按照烧水 - 冲泡 - 倒入杯中 - 加配料这一流程)完全一致,且不允许修改,只需把Beverage类的prepare方法修改为final类型即可

public abstract class Beverage {
	public void boilWater(){};
	
	public abstract void make();
	
	public void pourInCup(){};
	
	public abstract void add();
	
	public final void prepare(){
		boilWater();
		make();
		pourInCup();
		add();
	};
}

为所有的子类提供统一的固定的准备流程,这就是模板方法模式,这里面固定的流程即为模板方法模式定义中的算法骨架

子类可以在不改变算法流程的条件下,重新定义算法中的某些步骤,如:make方法和add方法由子类决定如何实现

上面的设计对流程的控制太过严苛,很难在实际应用中使用,当然通过一些改动,使子类除了能够决定特定步骤的具体实现方式之外,还可以对流程进行控制:


public abstract class Beverage {
	public void boilWater(){};
		
	public abstract void make();
		
	public void pourInCup(){};
		
	public abstract void add();
		
	public final void prepare(){
		boilWater();
		make();
		pourInCup();
		if(addOrNot()){
			add();
		}
	};
	
	protected boolean addOrNot(){
		return true;
	}
}
public class Coffee extends Beverage{
	public void make(){
		System.out.println("make coffee");
	};
	
	public void add(){
		System.out.println("add sugar");
	};
	
	protected boolean addOrNot(){
		try {
			System.out.println("Have some sugar?Y/N");
			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			String in = reader.readLine();
			if(null == in || in.equals("") || in.equals("N")){
				return false;
			}
			return true;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}
}
测试一下:

public class Test {
	public static void main(String[] args) {
		Beverage b = new Coffee();
		b.prepare();
	}
}
make coffee
Have some sugar?Y/N
Y
add sugar
make coffee
Have some sugar?Y/N
N

posted @ 2013-06-28 15:17  心意合一  阅读(251)  评论(0编辑  收藏  举报