设计模式之模板方法模式

咖啡冲泡法:

1、把水煮沸

2、用沸水冲泡咖啡

3、把咖啡倒进杯子

4、加糖和牛奶


茶冲泡法

1、把水煮沸

2、用沸水冲泡茶叶

3、把茶倒进杯子

4、加柠檬


写一写代码来创建茶和咖啡:

public class Coffee {
	void prepareRecipe(){
		boilWater();
		brewCoffeeGrinds();
		pourIncup();
		addSugarAndMilk();
	}
	
	public void boilWater(){
		System.out.println("Boiling water");
	}
	
	public void brewCoffeeGrinds(){
		System.out.println("Dripping Coffee through filter");
	}
	
	public void pourIncup(){
		System.out.println("Pouring into cup");
	}
	
	public void addSugarAndMilk(){
		System.out.println("Adding sugar and Milk");
	}

}

public class Tea {
	void prepareRecipe(){
		boilWater();
		steepTeaBag();
		pourIncup();
		addLemon();
	}
	
	public void boilWater(){
		System.out.println("Boiling water");
	}
	
	public void steepTeaBag(){
		System.out.println("Steeping the tea");
	}
	
	public void pourIncup(){
		System.out.println("Pouring into cup");
	}
	
	public void addLemon(){
		System.out.println("Adding lemon");
	}

}


仔细看看,咖啡和茶1、3步骤完全一样,可以放到基类中,2、4步骤实际也是一样,只是应用在不同的饮料。

抽象prepareRecipe()


public abstract class CaffeineBeverage {
	
	final void prepareRecipe(){
		boilWater();
		brew();
		pourInCup();
		addCondiments();
	}
	
	abstract void brew();
	abstract void addCondiments();
	
	void boilWater(){
		System.out.println("Boiling water");
	}
	
	void pourInCup(){
		System.out.println("Pouring into cup");
	}
}

public class Teaa extends CaffeineBeverage{

	@Override
	void brew() {
		// TODO Auto-generated method stub
		System.out.println("Steeping the tea");
	}

	@Override
	void addCondiments() {
		// TODO Auto-generated method stub
		System.out.println("Adding Lemon");
	}

}

public class Coffeee extends CaffeineBeverage{
	
	@Override
	void brew() {
		// TODO Auto-generated method stub
		System.out.println("Dripping coffee through filter");
	}

	@Override
	void addCondiments() {
		// TODO Auto-generated method stub
		System.out.println("Adding Sugar and Milk");
	}

}

相对于原来的:由CaffeineBeverage类主导一切,它拥有算法,而且保护这个算法。对子类来说,代码复用最大化。算法只存在一个地方,所以容易修改。


模板方法定义了一个算法的步骤,并允许子类为一个或者多个步骤提供实现。


还可以对模板方法进行挂钩:

public abstract class CaffeineBeverageWithHook {
	
	void prepareRecipe(){
		boilWater();
		brew();
		pourInCup();
		if(customerWantsCondiments())
			addCondiments();
	}
	
	abstract void brew();
	abstract void addCondiments();
	
	void boilWater(){
		System.out.println("Boiling water");
	}
	
	void pourInCup(){
		System.out.println("Pouring into cup");
	}
	
	boolean customerWantsCondiments(){
		return true;
	}

}

使用钩子:

public class CoffeeWithHook extends CaffeineBeverageWithHook{

	@Override
	void brew() {
		// TODO Auto-generated method stub
		System.out.println("Dripping coffee through filter");
	}

	@Override
	void addCondiments() {
		// TODO Auto-generated method stub
		System.out.println("Adding sugar and milk");
	}
	
	public boolean customerWantsCondiments(){
		String answer=getUserInput();
		
		if(answer.toLowerCase().startsWith("y")){
			return true;
		}else {
			return false;
		}
	}
	
	private String getUserInput(){
		String answerString=null;
		System.out.println("would you like milk and sugar with your coffee(y/n)");
		
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		try{
			answerString=in.readLine();
		}catch(IOException ioe){
			System.out.println("IO error");
		}
		if(answerString==null)
			return "no";
		return answerString;
	}

}

public class TeaWithHook extends CaffeineBeverageWithHook{
	@Override
	void brew() {
		// TODO Auto-generated method stub
		System.out.println("Steeping the tea");
	}

	@Override
	void addCondiments() {
		// TODO Auto-generated method stub
		System.out.println("Adding lemon");
	}
	
	public boolean customerWantsCondiments(){
		String answer=getUserInput();
		
		if(answer.toLowerCase().startsWith("y")){
			return true;
		}else {
			return false;
		}
	}
	
	private String getUserInput(){
		String answerString=null;
		System.out.println("would you like milk and sugar with your coffee(y/n)");
		
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		try{
			answerString=in.readLine();
		}catch(IOException ioe){
			System.out.println("IO error");
		}
		if(answerString==null)
			return "no";
		return answerString;
	}

}

test

public class BeverageTestDrive {
	public static void main(String[]args){
		
		TeaWithHook teaHook=new TeaWithHook();
		CoffeeWithHook coffeeHook=new CoffeeWithHook();
		
		System.out.println("\nMaking the tea...");
		teaHook.prepareRecipe();
		
		System.out.println("\nMaking the coffee...");
		coffeeHook.prepareRecipe();
	}

}

result

Making the tea...
Boiling water
Steeping the tea
Pouring into cup
would you like milk and sugar with your coffee(y/n)
n

Making the coffee...
Boiling water
Dripping coffee through filter
Pouring into cup
would you like milk and sugar with your coffee(y/n)
y
Adding sugar and milk


新的设计原则:好莱坞原则,防止依赖腐败。换句话说,高层组件对待底层组件的方式是“别调用我们,我们会调用你们”。


让我们来排序一些鸭子:利用数组的排序模板方法提供的算法

public class Duck implements Comparable{
	String name;
	int weight;
	
	public Duck(String name,int weight){
		this.name=name;
		this.weight=weight;
	}
	
	public String toString(){
		return name+"weights"+weight;
	}
	
	public int compareTo(Object object){
		Duck otherDuck=(Duck)object;
		
		if(this.weight<otherDuck.weight)
			return -1;
		else if(this.weight==otherDuck.weight){
			return 0;
		}else  return 1;
	}

}


import java.util.Arrays;

public class DuckSortTestDrive {
	public static void main(String[]args){
		Duck []ducks={
			new Duck("Daffy", 8),
			new Duck("Dewey", 2),
			new Duck("Howard", 7),
			new Duck("Louie", 2),
			new Duck("Huey", 2)
		};
		
		System.out.println("Before sorting:");
		display(ducks);
		
		Arrays.sort(ducks);
		
		System.out.println("\nAfter sorting:");
		display(ducks);
	}
	
	public static void display(Duck[]ducks){
		for(int i=0;i<ducks.length;i++)
			System.out.println(ducks[i]);
	}

}

result:

Before sorting:
Daffyweights8
Deweyweights2
Howardweights7
Louieweights2
Hueyweights2

After sorting:
Deweyweights2
Louieweights2
Hueyweights2
Howardweights7
Daffyweights8

模板方法和策略有点类似,但是模板方法 对算法有更多的控制权,而策略是通过对象组合的方式,让客户可以选择算法实现。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值