模板设计模式(封装算法)---- 抽象类的实际应用
OCP(开闭)原则:一个软件实体如类、模板、函数应该对扩展开放,对修改关闭。
1.模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供具体实现。
2.模板(模板方法)模式:ServerIet、AQS
在一个方法中定义一个算法的骨架,并将一些具体步骤延迟到子类中实现
模板模式使得子类可以在不改变算法的基础上,重新具体定义算法中的某些步骤。
例如:冲饮料的步骤:
1.烧开水;
2.把饮料倒进水里;
3.把泡好的饮料倒进杯子里;
4.加点儿调料;
冲饮料的步骤顺序不变,1和3也都一样,只有2和4在冲的饮料不同时所加的东西不同,所以可以将基本步骤封装在一个父类里,共同的步骤由父类实现,不同的步骤留给子类具体实现。
模板方法模式:
/*
* 基类声明为抽象类的原因是其子类必须实现其操作
* */
abstract class AbstractClass{
/*
* 模板方法,被声明为final以免子类改变这个算法的顺序
* */
final void templateMethod(){
}
/*
* 具体操作延迟到子类中实现
* */
abstract void primitiveOperation1();
abstract void primitiveOperation2();
/*
* 具体操作且共用的方法定义在超类中,可以被模板方法或子类直接使用
* */
final void concreteOperation(){
//实现
}
/*
* 钩子方法是一类“默认不做事的方法”
* 子类可以视情况决定要不要覆盖它们。
* */
void hook(){
//钩子方法
}
}
实现冲咖啡和茶:
abstract class CaffeineBeverage{
final void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
abstract void brew();
abstract void addCondiments();
public final void boilWater(){
System.out.println("1.烧开水!");
}
public final void pourInCup(){
System.out.println("3.倒进杯子里!");
}
public boolean customerWantsCondiments(){
return true;
}
}
class Tea extends CaffeineBeverage{
public void brew(){
System.out.println("2.把茶包放在开水里!");
}
public void addCondiments(){
System.out.println("4.加柠檬!");
}
@Override
public boolean customerWantsCondiments(){
String answer = getUserInput();
if(answer.equals("y")) {
return true;
}
else {
return false;
}
}
public String getUserInput(){
String answer = new String();
System.out.println("您想要在茶中加入柠檬吗?(y/n)");
Scanner scanner = new Scanner(System.in);
answer = scanner.nextLine();
return answer;
}
}
class Coffee extends CaffeineBeverage {
public void brew() {
System.out.println("2.把咖啡放在开水里!");
}
public void addCondiments() {
System.out.println("4.加牛奶和糖!");
}
//子类覆写了钩子函数,实现自定义功能
public boolean customerWantsCondiments() {
String answer = getUserInput();
if (answer.equals("y")) {
return true;
} else {
return false;
}
}
public String getUserInput() {
String answer = new String();
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 coffee = new Coffee();
CaffeineBeverage tea = new Tea();
System.out.println("咖啡制作中...");
coffee.prepareRecipe();
System.out.println("茶制作中...");
tea.prepareRecipe();
}
}