让一切变得更简单抽象化
深入封装算法块,这便是设计模式当中的一种模式:模板方法模式。
我们先来看看下面两个茶和咖啡配方
也许我们可以很快用Java代码实现出来,但我觉得做之前先分析分析,咖啡和茶的冲泡方式中第(1)步骤是完全一样的,我认为这样肯定会出现重复代码,写代码尽量不写重复代码,而第(2)(3)(4)步骤大体相似,
我们将两者步骤合起来看看
实现代码如下
咖啡因抽象类
package 改进之后;/*** 咖啡因饮料(抽象类) 带钩子方法 模板方法* * @author Joy* */
public abstract class CaffeineBeverageWithHook {// 制作流程public void prepareRecipe() {boilWater();brew();pourInCup();/** 加上一个条件,具体有customerWantsCondiments()方法决定,当用户“想要”调料时,才调用addCondiments()方法*/if (customerWantsCondiments()) {addCondiments();}}/*** 因为咖啡和茶都有这两个方法,但只是具体实现不同 所以这两个方法必须声明为抽象,具体实现交由子类*/// 冲泡的方法抽取出来public abstract void brew();// 加调料方法抽取出来public abstract void addCondiments();public void boilWater() {System.out.println("煮沸水");}public void pourInCup() {System.out.println("将饮料倒入杯子中");}/*** 定义一个方法(通常为空),这个方法只会返回true 这就是一个钩子方法 子类需根据需求是否覆盖这个方法* * @return*/// 添加一个新(“钩子”)方法,判断顾客是否需要添加调料public boolean customerWantsCondiments() {return true;}
}
咖啡类
package 改进之后;import java.util.Scanner;public class CoffeeWithHook extends CaffeineBeverageWithHook {@Overridepublic void brew() {System.out.println("把沸水冲泡咖啡");}@Overridepublic void addCondiments() {System.out.println("加糖加牛奶");}// 对此作出判断public boolean customerWantsCondiments() {String answer = getUserInput();if (answer.equals("y")) {return true;}System.out.println("咖啡不加调料");return false;}// 询问顾客是否需要加糖加奶private String getUserInput() {String answer = null;Scanner input = new Scanner(System.in);System.out.println("请问你是否需要在咖啡里加糖加奶呢?(y/n)");answer = input.next();if (answer.equals("y")) {return answer;} else if (answer.equals("n")) {return answer;} else {return "error";}}
}
茶类
package 改进之后;import java.util.Scanner;public class TeaWithHook extends CaffeineBeverageWithHook {@Overridepublic void brew() {System.out.println("把沸水浸泡茶叶");}@Overridepublic void addCondiments() {System.out.println("加柠檬");}@Overridepublic boolean customerWantsCondiments() {String answer = getUserInput();if (answer.equals("y")) {return true;}System.out.println("茶不加调料");return false;}// 询问顾客是否需要加糖加奶private String getUserInput() {String answer = null;Scanner input = new Scanner(System.in);System.out.println("请问你是否需要在茶里加柠檬呢?(y/n)");answer = input.next();if (answer.equals("y")) {return answer;} else if (answer.equals("n")) {return answer;} else {return "error";}}
}
测试类
package 改进之后;public class TestMain {public static void main(String[] args) {CoffeeWithHook coffeeHook = new CoffeeWithHook();TeaWithHook teaHook = new TeaWithHook();System.out.println("========制作咖啡");coffeeHook.prepareRecipe();System.out.println("\n========制作茶");teaHook.prepareRecipe();}
}
效果图
而所谓“钩子”方法其实是根据不同情况而做出不同响应结果的一种判断方法,这其我就实现一个最简单的钩子方法,根据y/n的输入得出用户是否要加入调料。
定义模板方法模式:在一个方法中定义一个算法的框架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。
注:模板就是一个方法,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类去实现。
感谢你看到这里,模板方法模式到这里就结束了,本人文笔随便,若有不足或错误之处望给予指点,90度弯腰~~~很快我会发布下一个设计模式的内容,生命不息,编程不止!