7.Java_模板设计模式---抽象类的实际应用(咖啡和茶的冲泡法),基于抽象类,核心是封装算法。引入钩子方法。开闭原则。23种设计模式
基于抽象类的模板设计模式,核心是封装算法。
1、模板方法定义了一个算法的步骤,允许子类为一个或多个步骤提供具体实现。
2、模板(模板方法)模式:(典型:Servlet),AQS
在一个方法中定义算法的框架,将一些具体步骤延迟到子类中实现。
模板模式可以使子类在不改变算法的基础上,重新定义算法中的某些具体步骤。
3.开闭原则(OCP):一个软件实体,如类、函数、模块应对扩展开放,对修改关闭。(Java中最重要的原则)
23种设计模式?23种设计模式详解
第三方解耦(提取公有过程到一个类中—公有类)
咖啡/茶的冲泡法:
两者本质不同,但在冲泡过程中却有相似的步骤:
1.将水煮沸
2.用热水泡饮料
3.把饮料倒进杯子
4.在饮料内加入适当的调料
//设计一个通用的方法来实现冲泡的过程
void prepareRecipe(){
boilWater();
brew();
pourInCup();
addCondiments();
}
模板设计模式:
//模板设计模式
abstract class CaffeineBeverage{
//用同一个方法冲泡茶个咖啡
final void prepareRecipe(){//final:不希望子类覆盖这个方法
boilWater();//烧水步骤相同
brew();
pourInCup();//倒入杯中步骤相同
addCondiments();
}
abstract void brew();
abstract void addCondiments();
void boilWater(){
System.out.println("Boiling water");
}
void pourInCup(){
System.out.println("Pouring into cup");
}
}
//处理茶类
class Tea extends CaffeineBeverage{
void brew(){
System.out.println("Steeping the tea");
}
void addCondiments(){
System.out.println("Adding Lemon");
}
}
//处理咖啡
class Coffee extends CaffeineBeverage{
void brew(){
System.out.println("Dripping Coffee through filter");
}
void addCondiments(){
System.out.println("Adding Sugar and Milk");
}
}
此时的类图为:
完整的模板模式超类的定义:
//基类声明为抽象类,子类必须实现操作
abstract class AbstractClass{
//模板方法,被声明为final以免子类改变算法的顺序
final void templateMethod(){
}
//具体操作延迟到子类实现
abstract void primitiveOperation1();
abstract void primitiveOperation2();
//具体操作、共用的方法定义在超类中,可以被模板方法或子类直接使用。
final void concreateOperation(){
//实现
}
//hook()是“默认不做事的方法”,子类可以根据情况决定是否覆盖它。
void hook(){
//钩子方法
}
}
扩展类,引入“钩子”方法:
abstract class CaffeineBeverage{
final void prepareRecipe(){
boilWater();
brew();
pourInCup();
//如果顾客想要加调料,才调用此加料方法
if(customerWantsCondiments()){
addCondiments();
}
}
abstract void brew();
abstract void addCondiments();
void boilWater(){
System.out.println("Boiling water");
}
void pourInCup(){
System.out.println("Pouring into cup");
}
//钩子方法,超类中通常默认实现,子类可以选择性的覆写此方法
boolean customerWantsCondiments(){
return true;
}
}
//处理茶类
class Tea extends CaffeineBeverage{
void brew(){
System.out.println("Steeping the tea");
}
void addCondiments(){
System.out.println("Adding Lemon");
}
}
//处理咖啡
class Coffee extends CaffeineBeverage{
void brew(){
System.out.println("Dripping Coffee through filter");
}
void addCondiments(){
System.out.println("Adding Sugar and Milk");
}
//子类覆写钩子方法,实现自定义功能
public boolean customerWantsCondiments(){
String answer = getUserInput();
if(answer.equals("y")){
return true;
}else{
return false;
}
}
private String getUserInput(){
String answer = null;
System.out.println("您想要在咖啡中假如牛奶或糖吗(y/n)?");
Scanner scanner = new Scanner(System.in);
answer=scanner.nextLine();
return answer;
}
}
public class Test{
public static void main(String[] args){
CaffeineBeverage tea = new Tea();
CaffeineBeverage coffee= new Coffee();
System.out.println("\nMaking tea...");
tea.prepareRecipe();
System.out.println("\nMaking coffee...");
coffee.prepareRecipe();
}
}