模板设计模式
**1.模板方法定义:**定义(或者说封装)一个算法的步骤,并允许子类为一个或多个子类提供具体实现。
学习设计模式方法:“找到第三方”. 第三方:模板类的模板方法。
**开闭原则(OCP):**一个软件实体,如类、函数、接口应该对阔扎开放、对修改关闭(即允许扩展,但不允许修改!)。
2.模板方法模式:
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤
3.模板模式优点与一般方法对比
一般方法 | 模范方法 |
---|---|
具体事物主导一切,控制算法 | 父类主导一切,它拥有算法,并且保护这个算法 |
同类型不同事物之间存在代码重复 | 存在父类,可以将代码最大限度复用 |
代码修改难度大 | 算法存于一个地方,容易修改 |
弹性差 | 弹性高,可以加入自定义方法 |
算法分散于许多类中 | 父类专注于算法本身,子类提供完整实现 |
4.示例
import java.util.Scanner;
abstract class CaffeineBeverage {// 核心算法
final void prepareRecipe(){//该类不会被子类覆盖//定义标准 不可修改
boilWater();
brew();
pourInCup();
if(customerWantsCondiments()){
addCondiments();
}
print();
}
/**
抽象方法 必须由子类实现
*/
abstract void brew();
abstract void addCondiments();
abstract void print();
/*
具体操作且共用的方法,定义在父类中,可被模板方法或子类直接直接使用
*/
void boilWater(){
System.out.println("Boiling water");
}
void pourInCup(){
System.out.println("Pouring into cuo");
}
/*
钩子方法 “默认不做事” 父类中通常默认实现 子类视情况决定要不要覆盖
*/
boolean customerWantsCondiments(){
return true;
}
}
/*
子类实现
*/
class Tea extends CaffeineBeverage{
void brew(){
System.out.println("Steeping the tea");
}
void addCondiments(){
System.out.println("Adding lemon");
}
void print(){
System.out.println("您的茶好了!");
}
}
class Coffee extends CaffeineBeverage{
void brew(){
System.out.println("Dripping Coffee through filter");
}
void addCondiments(){
System.out.println("Adding Suger 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;
}
void print(){
System.out.println("您的咖啡好了!");
}
}
public class Test26{
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();
}
}