デザインモード-テンプレート方法モード(template method pattern)詳細解


テンプレートの方法モード(template method pattern)の詳細
この記事のアドレス: http://blog.csdn.net/caroline_wendy
テンプレート方法モード:アルゴリズムの骨格を1つの方法で定義し、いくつかのステップをサブクラスに遅延させる. 
テンプレート方法は、サブクラスがアルゴリズム構造を変えずに、アルゴリズム中のいくつかのステップを再定義することを可能にする.
テンプレート方法はフック可能で、フックは抽象的なクラスにおいて宣言される方法であるが、空またはデフォルトの実装のみである.
フックの存在は、サブクラスがアルゴリズムの異なる点をフックできるようにすることができます.
抽象的なフレーム:
/**
 * @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)、継承(exted) 抽象類(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.テストクラス、フック操作を含む.
/**
 * @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("
Making tea..."); teaHook.prepareRecipe(); System.out.println("
Making 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