【Java笔记】模板设计模式(扩展"钩子"方法)(代码实现+总结)

1.模板设计模式

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

遵循开闭原则(OCP): 一个软件实体如类、模块和函数应该对扩展开放、对修改关闭。

下面看一个实际应用场景:

咖啡冲泡法:

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

茶冲泡法:

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

代码实现:

/**
模板设计模式
*/
public class TestTemplate{
	public static void main(String[] args){
		System.out.println("=========咖啡=========");
		Drink coffee = new Coffee();
		coffee.prepareDrink();
		System.out.println("=========柠檬茶=========");
		Drink tea = new Tea();
		tea.prepareDrink();
	}
}
abstract class Drink{
	//不希望子类覆盖这个方法,因此用final修饰
	final void prepareDrink(){
		boilWater();//烧水
		addMaterial();//添加主料
		brew();//冲泡
		pourInCup();//倒入杯子
		addIngredients();//添加辅料
	}
	//咖啡和茶处理这些方法不同,因此这两个方法必须被声明为抽象,留给子类实现
	abstract void addMaterial();
	abstract void addIngredients();
	void boilWater(){
		System.out.println("1.烧开水");
	}
	void brew(){
		System.out.println("3.冲泡饮品");
	}
	void pourInCup(){
		System.out.println("4.倒入杯子");
	}
}
class Coffee extends Drink{
	public void addMaterial(){
		System.out.println("2.加入咖啡粉");
	}
	public void addIngredients(){
		System.out.println("5.加糖加奶");
	}
}
class Tea extends Drink{
	public void addMaterial(){
		System.out.println("2.加入茶叶");
	}
	public void addIngredients(){
		System.out.println("5.加柠檬");
	}
}

运行结果:

【Java笔记】模板设计模式(扩展"钩子"方法)(代码实现+总结)

1.1引入"钩子"方法

超类中通常是默认实现,子类可以选择性的覆写此方法,实现自定义功能

代码实现:

/**
钩子方法
*/
import java.util.Scanner;

public class TestHook{
	public static void main(String[] args){
		System.out.println("=========咖啡=========");
		Drink coffee = new Coffee();
		coffee.prepareDrink();
	}
}
abstract class Drink{
	final void prepareDrink(){
		boilWater();//烧水
		addMaterial();//添加主料
		brew();//冲泡
		pourInCup();//倒入杯子
		if(customerWantIngredients()){
			addIngredients();//添加辅料
		}
	}
	abstract void addMaterial();
	abstract void addIngredients();
	void boilWater(){
		System.out.println("1.烧开水");
	}
	void brew(){
		System.out.println("3.冲泡饮品");
	}
	void pourInCup(){
		System.out.println("4.倒入杯子");
	}
	/**
	钩子方法:
	超类中通常是默认实现
	子类中可以选择覆写此方法
	*/
	boolean customerWantIngredients(){
		return true;
	}
}
class Coffee extends Drink{
	public void addMaterial(){
		System.out.println("2.加入咖啡粉");
	}
	public void addIngredients(){
		System.out.println("5.加糖加奶");
	}
	//子类覆写了钩子函数,实现自定义功能
	public boolean customerWantIngredients(){
		String answer = getUserInput();
		if("y".equals(answer)){
			return true;
		}else{
			return false;
		}
	}
	private String getUserInput(){
		String answer = null;
		System.out.println("您需要在咖啡中加糖或奶吗?(y/n)");
		Scanner sc = new Scanner(System.in);
		answer = sc.next();
		return answer;
	}
}

运行结果:

【Java笔记】模板设计模式(扩展"钩子"方法)(代码实现+总结)