您的位置:首页 > 编程语言 > Java开发

设计模式 - 模板方法模式(template method pattern) 详解

2014-06-18 19:31 686 查看

模板方法模式(template method pattern) 详解

本文地址: http://blog.csdn.net/caroline_wendy

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

模板方法可以进行挂钩(hook), 钩子(hook)是一种被声明在抽象类中的方法, 但只有空的或者默认的实现.
钩子的存在, 可以让子类有能力对算法的不同点进行挂钩.

抽象类的框架:
/**
* @time 2014年6月18日
*/
package template_method;

/**
* @author C.L.Wang
*
*/
public abstract class AbstractClass {

final void templateMethod() {
primitiveOperation1();
primitiveOperation2();
concreteOperation();
hook();
}

abstract void primitiveOperation1();

abstract void primitiveOperation2();

final void concreteOperation() {

}

void hook() {}
}


面向对象原则:
好莱坞原则: 别调用我们, 我们会调用你.

具体方法:
1. 抽象类(abstract class), 包含模板方法(template method), 抽象操作(abstract operation)
具体操作(concrete operation), 和钩子(hook).
/**
* @time 2014年6月18日
*/
package template_method;

/**
* @author C.L.Wang
*
*/
public abstract class CaffeineBeverage {

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;
}

}

2. 具体类(concrete class), 继承(extend) 抽象类(abstract class)./**
* @time 2014年6月18日
*/
package template_method;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* @author C.L.Wang
*
*/
public class CoffeeWithHook extends CaffeineBeverage {

/* (non-Javadoc)
* @see template_method.CaffeineBeverage#brew()
*/
@Override
void brew() {
// TODO Auto-generated method stub
System.out.println("Dripping Coffee through filter");
}

/* (non-Javadoc)
* @see template_method.CaffeineBeverage#addCondiments()
*/
@Override
void addCondiments() {
// TODO Auto-generated method stub
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.println("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.out.println("IO error trying to read your answer");
}

if (answer == null) {
return "no";
}

return answer;
}

}

/**
* @time 2014年6月18日
*/
package template_method;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* @author C.L.Wang
*
*/
public class TeaWithHook extends CaffeineBeverage {

/* (non-Javadoc)
* @see template_method.CaffeineBeverage#brew()
*/
@Override
void brew() {
// TODO Auto-generated method stub
System.out.println("Steeping the tea");
}

/* (non-Javadoc)
* @see template_method.CaffeineBeverage#addCondiments()
*/
@Override
void addCondiments() {
// TODO Auto-generated method stub
System.out.println("Adding Lemon");
}

public boolean customerWantsCondiments() {

String answer = getUserInput();

if (answer.toLowerCase().startsWith("y")) {
return true;
} else {
return false;
}

}

private String getUserInput() {

String answer = null;

System.out.println("Would you like lemon with your tea (y/n)? ");

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

try {
answer = in.readLine();
} catch (IOException ioe) {
System.out.println("IO error trying to read your answer");
}

if (answer == null) {
return "no";
}

return answer;
}

}

3. 测试类, 包含钩子(hook)操作./**
* @time 2014年6月18日
*/
package template_method;

/**
* @author C.L.Wang
*
*/
public class BeverageTestDrive {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TeaWithHook teaHook = new TeaWithHook();
CoffeeWithHook coffeeHook = new CoffeeWithHook();

System.out.println("\nMaking tea...");
teaHook.prepareRecipe();

System.out.println("\nMaking coffee...");
coffeeHook.prepareRecipe();
}

}

4. 输出:Making tea...
Boiling water
Steeping the tea
Pouring into cup
Would you like lemon with your tea (y/n)?
y
Adding Lemon

Making coffee...
Boiling water
Dripping Coffee through filter
Pouring into cup
Would you like milk and sugar with your coffee (y/n)?
n


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息