让一切变得更简单抽象化
深入封装算法块,这便是设计模式当中的一种模式:模板方法模式。
我们先来看看下面两个茶和咖啡配方
也许我们可以很快用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 {
@Override
public void brew() {
System.out.println("把沸水冲泡咖啡");
}
@Override
public 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 {
@Override
public void brew() {
System.out.println("把沸水浸泡茶叶");
}
@Override
public void addCondiments() {
System.out.println("加柠檬");
}
@Override
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 改进之后;
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度弯腰~~~很快我会发布下一个设计模式的内容,生命不息,编程不止!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。