设计模式——模板方法模式

来源:互联网 发布:重复玩 安卓游戏 知乎 编辑:程序博客网 时间:2024/06/03 16:01

10.

OO原则:好莱坞原则——别找(调用)我,我会(调用)找你。

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


例子:冲泡咖啡和茶的准备工作

public abstract class CaffeineBeverage {  final void prepareRecipe() {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");}}


public class Coffee extends CaffeineBeverage {public void brew() {System.out.println("Dripping Coffee through filter");}public void addCondiments() {System.out.println("Adding Sugar and Milk");}}


public class Tea extends CaffeineBeverage {public void brew() {System.out.println("Steeping the tea");}public void addCondiments() {System.out.println("Adding Lemon");}}


以下是上述类的关系图:


从上面我们可以看到,prepareRecipe()就是我们的模板方法,而brew()和addCondiments()需要子类提供方法实现。


若想让子类实现算法中的可选部分,或让子类对模板方法中的某些即将发生的步骤做出反应,可加入“钩子(hook)”方法:

public abstract class CaffeineBeverageWithHook { 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;}}



此处的customerWantsCondiments()就是一个“钩子”方法,它也可以是一个空的缺省实现,不做任何事情,而由子类来选择是否覆盖这个方法。


import java.io.*;public class CoffeeWithHook extends CaffeineBeverageWithHook { public void brew() {System.out.println("Dripping Coffee through filter");} public void addCondiments() {System.out.println("Adding Sugar and Milk");} public boolean customerWantsCondiments() {String answer = getUserInput();if (answer.toLowerCase().startsWith("y")) {return true;} else {return false;}} private String getUserInput() {String answer = null;System.out.print("Would you like milk and sugar with your coffee (y/n)? ");BufferedReader in = new BufferedReader(new InputStreamReader(System.in));try {answer = in.readLine();} catch (IOException ioe) {System.err.println("IO error trying to read your answer");}if (answer == null) {return "no";}return answer;}}



上面的getUserInput()询问客户是否需要加奶和糖,而customerWantsCondiments()调用此方法来实现父类的customerWantsCondiments(),作为一个条件来控制咖啡的生产过程。


在此比较一下策略模式、模板方法模式、工厂方法模式:

策略模式:封装可互换的行为,然后使用委托来决定要采用哪一个行为;(用组合实现)

模板方法模式:子类决定如何是想算法中的步骤;(用继承实现)

工厂方法模式:由子类决定实例化那个具体类。(模板方法模式的一个特殊版本)



原创粉丝点击