java—基于抽象类的模板设计模式(星巴克咖啡冲泡法的优化及扩展)

基于抽象类的模板设计模式

模板设计模式:
在一个方法中定义一个算法的骨架(在父类中定义),将一些步骤延迟到子类。
模板方法使得子类可以在不改变算法的情况下,重新定义算法的某些步骤。
在父类中对相同的方法直接定义,并且使用final修饰;
对于结构相同的方法,可以只声明方法,定义为抽象方法,具体实现在子类中实现;
修改流程只需要在父类中修改。


星巴克咖啡冲泡法

  1. 将水煮沸
  2. 用沸水冲泡咖啡
  3. 将咖啡倒进杯子
  4. 加糖和牛奶

星巴克茶冲泡法

  1. 将水煮沸
  2. 用沸水浸泡茶叶
  3. 把茶倒进杯子
  4. 加柠檬

普通方法

按照流程可具体实现如下:

public class Test0002{
	public static void main(String[] args){
		
		Coffee coffee = new Coffee();
		coffee.process();
		System.out.println("----------------------");
		Tea tea = new Tea();
		tea.process();
	}
}

//制作咖啡的流程
class Coffee{

	public void process(){
		this.boilWater();
		this.putWaterInputCup();
		this.putCoffeeInputCup();
		this.addMilkOrSugar();
	}
	
	public void boilWater(){
		System.out.println("1,将水煮沸");
	}
	
	public void putWaterInputCup(){
		System.out.println("2,将水倒入杯中");
	}
	
	public void putCoffeeInputCup(){
		System.out.println("3,将咖啡倒入水中");
	}
	
	public void addMilkOrSugar(){
		System.out.println("4,加牛奶或者糖");
	}
}

//制作茶的流程
class Tea{
	
	public void process(){
		this.boilWater();
		this.putWaterInputCup();
		this.putTeaInputCup();
		this.addLemon();
	}
	
	public void boilWater(){
		System.out.println("1,将水煮沸");
	}
	
	public void putWaterInputCup(){
		System.out.println("2,将水倒入杯中");
	}
	
	public void putTeaInputCup(){
		System.out.println("3,将茶叶倒入水中");
	}
	
	public void addLemon(){
		System.out.println("4,加柠檬");
	}
}

运行结果如下:
java—基于抽象类的模板设计模式(星巴克咖啡冲泡法的优化及扩展)_第1张图片
从以上代码可以看出,制作咖啡的流程和制作茶的流程有相同的部分,此时我们可以考虑简化代码,简化思路如下:

  • 每个类中都有process()方法,而且该方法中的方法体都不相同,可以考虑将process()方法改为抽象方法,交由子类去实现;
    但是,仔细观察process()方法中的方法体,该方法体中分别是制作咖啡和制作茶的流程,前两个步骤都是(1,将水煮沸 2,将水倒入杯中),第三个步骤是分别将咖啡 和 茶倒入水中,考虑到还有其他饮品的制作,可以改成(3,将 制作材料加入水中),第四个步骤可以类似,改为(4,加入辅料)。
    此时process()方法就是一个制作饮品的固定流程方法,可以不定义为抽象的,而且不能被子类所覆写,用final 修饰。

  • 制作饮品的每个类中都有boilWater()方法 和 putWaterIuputCup()方法,可以将这两个方法定义在父类中,且用final 修饰,不需要子类覆写。

  • 前面讲过,可以将流程3 和 流程4 分别改为(3,将制作材料加入水中)(4,将辅料加入水中),这两个方法没有具体实现,所以需要定义为抽象方法,具体实现交由子类实现。

  • 为了使子类对父类方法中的流程更具有灵活性,可以适当添加一些判断条件。

优化后的方法如下:

//1,父类,制作饮品
abstract class Drink{
//1.1 制作饮品的流程
	 public final void makeDrink(){
		 this.boilWater();
		 this.putWaterInputCup();
		 this.putMagorInputCup();
//1.2 对于是否添加辅料,可以灵活变通
		 if(this.isAddOthers()){
			this.addOthersInputCup();
		 }
		 
	 }
//1.3 	流程中的两个固定方法 ,且不可修改
	 public final void boilWater(){
		 System.out.println("1,将水煮沸");
	 }
	 public final void putWaterInputCup(){
		 System.out.println("2,将水倒入杯中");
	 }
//1.4 流程中的两个抽象方法,加材料和加辅料,具体实现交由子类完成。 
	 public abstract void putMagorInputCup();
	 public abstract void addOthersInputCup();
//1.5 对于是否添加辅料,要在子类中具体确定
	 public boolean isAddOthers(){
		 return true;
	 }
}

//2,咖啡的制作流程
class Coffee extends Drink{
	public void putMagorInputCup(){
		System.out.println("3,将咖啡倒入水中");
	}
	public void addOthersInputCup(){
		System.out.println("4,加牛奶或者糖");
	}
}

//3,茶的制作流程
//在tea子类的具体实现中,判断要不要加辅料
class Tea extends Drink{
	private boolean isAddOthers = true;
	
	public Tea(boolean isAddOthers){
		this.isAddOthers = isAddOthers;
	}
	public void putMagorInputCup(){
		System.out.println("3,将茶叶倒入水中");
	}
	public void addOthersInputCup(){
		System.out.println("4,加柠檬");
	}
	
	public boolean isAddOthers(){
		return isAddOthers;
	}
}

//4, 果汁的制作流程
class Juice extends Drink{
	public void putMagorInputCup(){
		System.out.println("3,将浓缩果汁倒入水中");
	}
	public void addOthersInputCup(){
		System.out.println("4,加冰块");
	}
}

//定义测试类,实例化对象
public class Test0002{
	public static void main(String[] args){
		
		Drink coffee = new Coffee();
		coffee.makeDrink();
		 System.out.println("----------------------");
		 Drink tea = new Tea(false);
		 tea.makeDrink();
		 System.out.println("----------------------");
		 Drink juice = new Juice();
		 juice.makeDrink();
	}
}

结果如下:
java—基于抽象类的模板设计模式(星巴克咖啡冲泡法的优化及扩展)_第2张图片
由以上代码可以发现:优化后的代码有了固定的制作流程,添加一种新饮品的制作也很方便。
而且如果要修改制作流程,可以只在父类方法中修改,不需要在每个子类中修改。

你可能感兴趣的:(Java)