目的
對於方法,只先定義好演算法的骨架,某些步驟則留給子類別去填埔,以便在不改變演算法整體構造的情況下讓子類別去精鍊某些步驟。
Define the skeleton of an algorithm (a base method), called a template method which defers some steps to subclasses. So, the algorithm structure is the same (without changing the algorithm’s structure) but some of its steps can be redefined by the subclasses according to the context.
適用
- 希望演算法不變之處只寫一次,可變之處則留給子類別去實作時。
- 如果許多子類別都會有共同的行為,就應該抽取出來集中至另一個共同的類別,避免重複。
- 希望能控制子類別的擴充範圍(掛鉤)時。
結構及成員
Collaborations: ConcreteClass仰賴AbstractClass製作出演算法的不變之處。
影響結果
實作
減少PrimitiveOperation的數目。愈多要覆寫的方法,別人就得做更多的瑣事
命名慣例:可替應覆寫的方法名稱加上固定的前綴字眼,如「doMethodXXX()」等等。
Example: Template with Hook
Abstract Class: RobotHookTemplate
package hook.robot;
public abstract class RobotHookTemplate
{
public final void go()
{
start();
getParts();
assemble();
if (testOK()){
test();
}
stop();
}
public void start()
{
System.out.println("Starting....");
}
public void getParts()
{
System.out.println("Getting parts....");
}
public void assemble()
{
System.out.println("Assembling....");
}
public void test()
{
System.out.println("Testing....");
}
public void stop()
{
System.out.println("Stopping....");
}
public boolean testOK()
{
return true;
}
}
Class: CookieHookRobot
package hook.robot;
public class CookieHookRobot extends RobotHookTemplate
{
private String name;
public CookieHookRobot(String n)
{
name = n;
}
public void getParts()
{
System.out.println("Getting a flour and sugar....");
}
public void assemble()
{
System.out.println("Baking a cookie....");
}
public String getName()
{
return name;
}
public boolean testOK()
{
return false;
}
}
Class: TestHookTemplate
package hook.robot;
public class TestHookTemplate
{
public static void main(String args[])
{
CookieHookRobot cookieHookRobot =
new CookieHookRobot("Cookie Robot");
System.out.println(cookieHookRobot.getName() + ":");
cookieHookRobot.go();
}
}
Result:
Cookie Robot:
Starting....
Getting a flour and sugar....
Baking a cookie....
Stopping....