您的位置:首页 > 其它

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

2017-08-04 11:29 274 查看
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(),作为一个条件来控制咖啡的生产过程。

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

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

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

工厂方法模式:由子类决定实例化那个具体类。(模板方法模式的一个特殊版本)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式