一、UML圖
關鍵詞:骨架。
二、概念
模板方法模式:定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
三、說明
角色:
(1)AbstractClass:是抽象類,其實也就是一個抽象模板,定義並實現了一個模板方法。這個模板方法一般是一個具體方法,它給出了一個頂級邏輯的框架,而邏輯的組成步驟在相應的抽象操作中,推遲到子類實現。頂級邏輯也有可能調用一些具體方法。
(2)ConcreteClass:實現父類所定義的一個或多個抽象方法。每一個AbstractClass都可以有任意多個ConcreteClass與之對應,而每一個ConcreteClass都可以給出這些抽象方法(也就是頂級邏輯的組成步驟)的不同實現,從而使得頂級邏輯的實現各不相同。
總結:當不變的和可變的行爲在方法的子類實現中混合在一起的時候,不變的行爲就會在子類中重複出現。我們通過模板方法模式,把這些行爲搬移到單一的地方,這樣幫助子類擺脫重複的不變行爲的糾纏。
注意:在《大話設計模式》的例子中,AbstractClass爲TestPaper類,ConcreteClass爲TestPaperA和TestPaperB,而上述的UML圖中的TemplateMethod()爲TestQuestion1(),primitiveOperation1爲函數Answer1(),primitiveOperation1爲函數Answer2()等等。
四、C++實現
(1)TestPaper.h:
#ifndef TESTPAPER_H
#define TESTPAPER_H
#include <iostream>
#include <string>
//AbstractClass,實現了一個模板,定義了算法的骨架,組成骨架的具體步驟放在子類中實現
class TestPaper
{
public:
void TestQuestion1()
{
std::cout<<"楊過得到,後來給了郭靖,練成倚天劍、屠龍刀的玄鐵可能是【】a.球磨鑄鐵 b.馬口鐵 c.高速合金鋼 d.碳素纖維"<<std::endl;
std::cout<<"答案:"<<Answer1()<<std::endl;
}
void TestQuestion2()
{
std::cout<<"楊過、程英、陸無雙剷除了情花,造成【】a.使這種植物不再害人 b.使一種珍稀物種滅絕 c.破壞了那個生物圈的生態平衡 d.造成該地區沙漠化"<<std::endl;
std::cout<<"答案:"<<Answer2()<<std::endl;
}
void TestQuestion3()
{
std::cout<<"藍鳳凰致使華山師徒、桃谷六仙嘔吐不止,如果你是大夫,會給他們開什麼藥【】a.阿司匹林 b.牛黃解毒片 c.氟哌酸 d.讓他們喝大量牛奶"<<std::endl;
std::cout<<"答案:"<<Answer3()<<std::endl;
}
protected:
virtual std::string Answer1()
{
return "";
}
virtual std::string Answer2()
{
return "";
}
virtual std::string Answer3()
{
return "";
}
};
//ConcreteClass,實現具體步驟
class TestPaperA:public TestPaper
{
protected:
virtual std::string Answer1()
{
return "b";
}
virtual std::string Answer2()
{
return "c";
}
virtual std::string Answer3()
{
return "a";
}
};
//ConcreteClass,實現具體步驟
class TestPaperB:public TestPaper
{
protected:
virtual std::string Answer1()
{
return "c";
}
virtual std::string Answer2()
{
return "a";
}
virtual std::string Answer3()
{
return "a";
}
};
#endif
(2)main.cpp:
#include "TestPaper.h"
#include <iostream>
#include <cstdlib>
//Client,客戶端
void main()
{
std::cout<<"學生甲抄的試卷:"<<std::endl;
TestPaper* studentA=new TestPaperA();
studentA->TestQuestion1();
studentA->TestQuestion2();
studentA->TestQuestion3();
std::cout<<std::endl;
std::cout<<"學生乙抄的試卷:"<<std::endl;
TestPaper* studentB=new TestPaperB();
studentB->TestQuestion1();
studentB->TestQuestion2();
studentB->TestQuestion3();
std::cout<<std::endl;
delete studentA;
delete studentB;
system("pause");
}
(3)運行結果: