在一個(gè)方法中定義一個(gè)算法的框架,并將該算法的某些步驟,延遲到子類實(shí)現(xiàn)。Template Method使得子類可以重新定義一個(gè)算法中的某些特定的步驟,而無(wú)需改變整個(gè)算法的結(jié)構(gòu)。
“Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.” - GoF
換言之,Template Method提供一個(gè)方法,以允許子類重寫(xiě)該方法的一部分,而無(wú)需重寫(xiě)整個(gè)子類。
比如,對(duì)于某一項(xiàng)任務(wù),如果它有一個(gè)復(fù)雜的成員函數(shù),并且該成員函數(shù)可以分成幾個(gè)步驟,同時(shí)這幾個(gè)步驟構(gòu)成成員函數(shù)的整體結(jié)構(gòu)式穩(wěn)定的,但各個(gè)子步驟卻有很多改變的需求,這樣的情形下就特別適合使用Template Method。Template Method設(shè)計(jì)模式就是在確定穩(wěn)定的成員函數(shù)組成結(jié)構(gòu)的前提下,應(yīng)對(duì)各個(gè)子步驟的變化。
Template Method模式之UML類圖:
業(yè)務(wù)示例:
測(cè)試各種不同的小汽車。
//TemplateMethod.h
#include <iostream>
using namespace std;
class TestVehicle
{
public:
void test() // 測(cè)試。這就是Template Method。它一共由6個(gè)步驟按照一定的時(shí)間
{ // 順序組成,但各個(gè)步驟的實(shí)現(xiàn)被延遲到TestVehicle的子類
cout << "Start to test...." << endl; // 模擬固定部分的代碼
start_up(); // 啟動(dòng)
blow_horn(); // 按喇叭
run(); // 行駛
turn(); // 轉(zhuǎn)彎
brake(); // 剎車
stop(); // 停車
cout << "Test finished..." << endl; // 模擬固定部分的代碼
}
virtual ~TestVehicle()
{
cout << "in the destructor of TestVehicle..." << endl;
}
protected:
virtual void start_up() = 0;
virtual void blow_horn() = 0;
virtual void run() = 0;
virtual void turn() = 0;
virtual void brake() = 0;
virtual void stop() = 0;
};
// 測(cè)試帕沙特
class TestPassat : public TestVehicle
{
public:
~TestPassat()
{
cout << "in the destructor of TestPassat..." << endl;
}
protected:
void start_up()
{
cout << "--- Passat:\tstart up ---" << endl; // 模擬啟動(dòng)Passat
}
void blow_horn()
{
cout << "--- Passat:\tblow the horn ---" << endl; // 模擬按Passat的喇叭
}
void run()
{
cout << "--- Passat:\trun ---" << endl; // 模擬Passat行駛
}
void turn()
{
cout << "--- Passat:\ttrun ---" << endl; // 模擬Passat轉(zhuǎn)彎
}
void brake()
{
cout << "--- Passat:\tbrake ---" << endl; // 模擬Passat剎車
}
void stop()
{
cout << "--- Passat:\tstop ---" << endl; // 模擬Passat停車
}
};
// 測(cè)試捷達(dá)
class TestJetta : public TestVehicle
{
public:
~TestJetta()
{
cout << "in the destructor of TestJetta..." << endl;
}
protected:
void start_up()
{
cout << "--- Jetta:\tstart up ---" << endl; // 模擬按Jetta的喇叭
}
void blow_horn()
{
cout << "--- Jetta:\tblow the horn ---" << endl; // 模擬按Jetta的喇叭
}
void run()
{
cout << "--- Jetta:\trun ---" << endl; // 模擬Jetta行駛
}
void turn()
{
cout << "--- Jetta:\ttrun ---" << endl; // 模擬Jetta轉(zhuǎn)彎
}
void brake()
{
cout << "--- Jetta:\tbrake ---" << endl; // 模擬Jetta剎車
}
void stop()
{
cout << "--- Jetta:\tstop ---" << endl; // 模擬Jetta停車
}
};
// TemplateMethod.cpp
#include "TemplateMethod.h"
int main(int argc, char** argv)
{
// 測(cè)試帕沙特
TestVehicle *tvPassat = new TestPassat();
tvPassat->test();
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
// 測(cè)試捷達(dá)
TestVehicle *tvJetta = new TestJetta();
tvJetta->test();
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
delete tvPassat;
delete tvJetta;
return 0;
}
運(yùn)行結(jié)果:
Start to test....
--- Passat: start up ---
--- Passat: blow the horn ---
--- Passat: run ---
--- Passat: trun ---
--- Passat: brake ---
--- Passat: stop ---
Test finished...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Start to test....
--- Jetta: start up ---
--- Jetta: blow the horn ---
--- Jetta: run ---
--- Jetta: trun ---
--- Jetta: brake ---
--- Jetta: stop ---
Test finished...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
in the destructor of TestPassat...
in the destructor of TestVehicle...
in the destructor of TestJetta...
in the destructor of TestVehicle...
上述程序的UML類圖:
Template Method模式應(yīng)該是GoF給出的23個(gè)模式中相對(duì)簡(jiǎn)單的一個(gè)。