在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模版方法使子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。模板就是一个方法。更具体的说,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现。这可以确保算法的结构保持不变,同时由子类提供部分实现。
1 。模版方法定义了算法的步骤,把这些步骤地实现延迟到子类。
2。模版方法模式为我们提供了一种代码复用的重要技巧。
3。模版方法的抽象类可以定义具体的方法,抽象的方法和钩子。
4。抽象方法由子类实现。
5。钩子是一种方法,它在抽象类中不做事,或者只做默认的事情,资料可以选择要不要去覆盖它。
6。为了防止子类改变模版方法中的算法,可以将模版声明为final。
7。好莱坞原则告诉我们,将决策权放在高层模块中,以便决定如何以及何时调用底层模块。
8。你将在真实世界 代码中看到模版方法模式的许多变体,不要期待他们全部是 一眼就可以被你认出的。
9。策略模式和模版方法模式都封装算法,一个用组合一个用继承。
10。工厂方法是模版方法的一种特殊版本。
package pattern;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
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");
}
}
class Tea extends CaffeineBeverage{
public void brew(){
System.out.println("Steeping the tea");
}
public void addCondiments(){
System.out.println("Adding Lemon");
}
}
class Coffee extends CaffeineBeverage{
public void brew(){
System.out.println("Dripping Coffee through filter");
}
public void addCondiments(){
System.out.println("Adding Sugar and Milk");
}
}
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;
}
}
class TeaWithHook extends CaffeineBeverageWithHook{
public void brew(){
System.out.println("Steeping the tea");
}
public void addCondiments(){
System.out.println("Adding Lemon");
}
}
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.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.err.println("IO error trying to read your answer");
}
if(answer==null){
return "no";
}
return answer;
}
}
package pattern;
public class BeverageTestDrive {
public static void main(String[] args) {
TeaWithHook teaHook=new TeaWithHook();
CoffeeWithHook coffeeHook=new CoffeeWithHook();
System.out.println("\nMaking tea...");
teaHook.prepareRecipe();
System.out.println("\nMaking coffee...");
coffeeHook.prepareRecipe();
}
}
package pattern;
import java.util.Arrays;
public class DuckSortTestDrive {
public static void main(String[] args) {
DuckSort[] ducks = { new DuckSort("Daffy", 8),
new DuckSort("Dewey", 2), new DuckSort("Howard", 7),
new DuckSort("Louie", 2), new DuckSort("Donald", 10),
new DuckSort("Huey", 2) };
System.out.println("Bdfore sorting:");
display(ducks);
Arrays.sort(ducks);
System.out.println("\nAfter sorting:");
display(ducks);
}
static void display(DuckSort[] ducks) {
for (int i = 0; i < ducks.length; i++) {
System.out.println(ducks[i]);
}
}
}
class DuckSort implements Comparable {
String name;
int weight;
public DuckSort(String name, int weight) {
this.name = name;
this.weight = weight;
}
public String toString() {
return name + " weighs " + weight;
}
public int compareTo(Object object) {
DuckSort otherDuck = (DuckSort) object;
if (this.weight < otherDuck.weight) {
return -1;
} else if (this.weight == otherDuck.weight) {
return 0;
} else {
return 1;
}
}
}
package pattern;
public class DuckTestDrive {
public static void main(String[] args) {
DuckInterface duck=new MallardDuckinterface();
WildTurkey turkey= new WildTurkey();
DuckInterface turkeyAdapter=new TurkeyAdapter(turkey);
Turkey duckAdapter=new DuckAdapter(duck);
System.out.println("The Turkey says...");
turkey.gobble();
turkey.fly();
System.out.println("\n The Duck says...");
testDuck(duck);
System.out.println("\n The TurkeyAdapter says...");
//testDuck(turkeyAdapter);
//turkeyAdapter.quack();
duckAdapter.fly();
}
static void testDuck(DuckInterface duck){
duck.quack();
duck.fly();
}
}