作用:
定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。TemplateMethod 使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
UML結構圖:
抽象基類:
1)AbstractClass:抽象基類,定義算法的輪廓
解析:
TemplateMethod 的關鍵在於在基類中定義了一個算法的輪廓,但是算法每一步具體的實現留給了派生類.但是這樣也會造成設計的靈活性不高的缺點,因為輪廓已經定下來了要想改變就比較難了,這也是為什麼優先采用聚合而不是繼承的原因.
實現:
1)TemplateMethod.h
/**//********************************************************************
created: 2006/07/20
filename: TemplateMethod.h
author: 李創
http://www.cppblog.com/converse/
purpose: TemplateMethod模式的演示代碼
*********************************************************************/
// 抽象基類,定義算法的輪廓
class AbstractClass
{
public:
AbstractClass(){}
virtual ~AbstractClass(){}
// 這個函數中定義了算法的輪廓
void TemplateMethod();
protected:
// 純虛函數,由派生類實現之
virtual void PrimitiveOperation1() = 0;
virtual void PrimitiveOperation2() = 0;
};
// 繼承自AbstractClass,實現算法
class ConcreateClass
: public AbstractClass
{
public:
ConcreateClass(){}
virtual ~ConcreateClass(){}
protected:
virtual void PrimitiveOperation1();
virtual void PrimitiveOperation2();
};
2)TemplateMethod.cpp
/**//********************************************************************
created: 2006/07/20
filename: TemplateMethod.cpp
author: 李創
http://www.cppblog.com/converse/
purpose: TemplateMethod模式的演示代碼
*********************************************************************/
#include "TemplateMethod.h"
#include <iostream>
void AbstractClass::TemplateMethod()
{
PrimitiveOperation1();
PrimitiveOperation2();
}
void ConcreateClass::PrimitiveOperation1()
{
std::cout << "PrimitiveOperation1 by ConcreateClass\n";
}
void ConcreateClass::PrimitiveOperation2()
{
std::cout << "PrimitiveOperation2 by ConcreateClass\n";
}
3)Main.cpp
/**//********************************************************************
created: 2006/07/20
filename: Main.cpp
author: 李創
http://www.cppblog.com/converse/
purpose: TemplateMethod模式的測試代碼
*********************************************************************/
#include "TemplateMethod.h"
#include <stdlib.h>
int main()
{
AbstractClass* pConcreateClass = new ConcreateClass;
pConcreateClass->TemplateMethod();
delete pConcreateClass;
system("pause");
return 0;
}