模板方法模式(Template Method Pattern)

来源:互联网 发布:java web mvc书 编辑:程序博客网 时间:2024/06/05 04:45

模板方法模式定义:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的条件下,重新定义算法中的某些步骤

例如:准备一杯咖啡与准备一杯柠檬茶有很多相同步骤:

准备咖啡:烧水- 冲泡咖啡 - 倒入杯中 - 加糖

准备柠檬茶:烧水- 冲泡茶 - 倒入杯中 - 加柠檬


public class Coffee {public void boilWater(){};public void makeCoffee(){};public void pourInCup(){};public void addSugar(){};public void prepareCoffee(){boilWater();makeCoffee();pourInCup();addSugar();};}

通常的做法是抽象出一个共同的父类,将相同的步骤移至父类中:


public class Beverage {public void boilWater(){};public void pourInCup(){};}
public class Coffee extends Beverage{public void makeCoffee(){};public void addSugar(){};public void prepareCoffee(){boilWater();makeCoffee();pourInCup();addSugar();};}

简洁多了,但是仔细观察,冲泡咖啡与冲泡茶可以抽象为冲泡方法,加糖与加柠檬可以抽象为加配料方法:

public abstract class Beverage {public void boilWater(){};public abstract void make();public void pourInCup(){};public abstract void add();}
public class Coffee extends Beverage{public void make(){System.out.println("make coffee");};public void add(){System.out.println("add sugar");};public void prepareCoffee(){boilWater();this.make();pourInCup();this.add();};}

此时已经可以清楚的发现,prepareCoffee与prepareTea的步骤已经完全一样了,可抽象至共同父类Beverage中


public abstract class Beverage {public void boilWater(){};public abstract void make();public void pourInCup(){};public abstract void add();public void prepare(){boilWater();make();pourInCup();add();};}
public class Coffee extends Beverage{public void make(){System.out.println("make coffee");};public void add(){System.out.println("add sugar");};}

如果想要实现特定的准备咖啡流程,只需在Coffee类中重写Beverage的prepare方法即可

如果想要Beverage类所有子类的准备流程(必须严格按照烧水 - 冲泡 - 倒入杯中 - 加配料这一流程)完全一致,且不允许修改,只需把Beverage类的prepare方法修改为final类型即可

public abstract class Beverage {public void boilWater(){};public abstract void make();public void pourInCup(){};public abstract void add();public final void prepare(){boilWater();make();pourInCup();add();};}

为所有的子类提供统一的固定的准备流程,这就是模板方法模式,这里面固定的流程即为模板方法模式定义中的算法骨架

子类可以在不改变算法流程的条件下,重新定义算法中的某些步骤,如:make方法和add方法由子类决定如何实现

上面的设计对流程的控制太过严苛,很难在实际应用中使用,当然通过一些改动,使子类除了能够决定特定步骤的具体实现方式之外,还可以对流程进行控制:


public abstract class Beverage {public void boilWater(){};public abstract void make();public void pourInCup(){};public abstract void add();public final void prepare(){boilWater();make();pourInCup();if(addOrNot()){add();}};protected boolean addOrNot(){return true;}}
public class Coffee extends Beverage{public void make(){System.out.println("make coffee");};public void add(){System.out.println("add sugar");};protected boolean addOrNot(){try {System.out.println("Have some sugar?Y/N");BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String in = reader.readLine();if(null == in || in.equals("") || in.equals("N")){return false;}return true;} catch (IOException e) {e.printStackTrace();return false;}}}
测试一下:

public class Test {public static void main(String[] args) {Beverage b = new Coffee();b.prepare();}}
make coffeeHave some sugar?Y/NYadd sugar
make coffeeHave some sugar?Y/NN

原创粉丝点击