【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.加柠檬");
}
}
运行结果:
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;
}
}
运行结果: