目的
定义一个操作中的算的骨架,将一些步骤的具体实现延迟到子类中,模板方法模式使得子类可以不改变一个算法的结构就可以重新定义该算法的某些特定步骤。
案例
一个含有Application和Document类的应用框架,Application类负责打开一个外部文档,当文档中的内容读入之后,就用Document来表示。在Application中存在方法openDocument进行文档的操作:
void Application::openDocument(const char* name)
{
if(!canOpenDocument(name))
return;
Document* doc = createDocument();
if(doc != NULL)
{
m_docs->addDocument(doc);
aboutToOpenDocument(doc);
doc->open();
doc->read();
}
}
在Application的openDocument中定义了打开一个文档的每一个主要步骤,它检查了文档是否能被打开,并创建与应用相关的Document对象,并且从文件中读入该Document,此时openDocument就是
模板方法。一个模版方法用一些抽象的操作定义一个算法,而子类将重定义这些操作以提供具体的行为:
类Application提供需要子类重定义的操作:
class Application
{
public:
void openDocument(const char* name);
protected:
virtual void canOpenDocument(const char* name);
virtual void createDocument();
virtual void aboutToOpenDocument();
private:
vector<Document*> m_docs;
};
MyApplication自需要是实现自己需要重定义的操作:
class MyApplication : public Application
{
protected:
virtual Document* createDocument();
virtual void aboutToOpenDocument();
};
Document* MyApplication::createDocument()
{
return new MyDocument();
}
void aboutToOpenDocument()
{
// initialize doc object.
}
Document和MyDocument也是类似的实现。
适用性
- 一次性定义一个算法的不变的部分,将可变的行为留给子类来实现。
- 各子类中公共的行为应该提取出来,并集中到一个公共父类中以避免代码重复。
- 控制子类扩展。