目錄
- “組件協作”模式
- 模板方法模式
- 動機
- 模式定義
- 結構
- 要點總結
“組件協作”模式
- 現代軟件專業分工之后的第一個結果是“框架與應用程序的劃分”。“組件協作”模式通過晚期綁定,實現框架與應用程序之間的松耦合,是二者之間協作時常用的模式。
- 典型模式,以下模式在“組件協作”這一層面體現更明顯
- 模板方法模式 Template Method
- 觀察者模式 Observer / Event
- 策略模式 Strategy
模板方法模式
動機
- 在軟件構建過程中,對于某一項任務,它常常有穩定的整體操作結構,但各個子步驟卻有很多改變的需求,或者由于固有的原因(比如框架與應用之間的關系)子步驟無法和任務的整體結構同時實現。
- 如何在確定穩定操作結構的前提下,來靈活應對各個子步驟的變化或者晚期實現需求?
- 結構化軟件設計思維流程
// templateLib.cpp 程序庫開發人員
class Library
{
public:void Step1(){...}void Step3(){...}void Step5(){...}
};// templateApplication.cpp 應用程序開發人員
class Application
{
public:bool Step2(){...}void Step4(){...}
};// main.cpp 應用程序開發人員
int main()
{Library lib();Application app();// 應用程序開發人員編寫主流程lib.Step1()if(app.Step2()){lib.Step3()}for (int i = 0; i < 3; i++){app.Step4();}lib.Step(5);
}
- 面向對象軟件設計思維流程
// templateLib.cpp 程序庫開發人員
class Library
{
public:// 穩定 template method,穩定中支持變化void Run(){// 程序庫開發人員編寫主流程Step1();if(Step2()) // 支持變化,虛函數的多態調用{Step3();}for (int i = 0; i < 4; i++){Step4(); // 支持變化,虛函數的多態調用}Step5();}virtual ~Library(){ } // 基類析構函數寫為虛函數protected:void Step1() // 穩定{...}void Step3() // 穩定{...}void Step5() // 穩定{...}virtual bool Step2() = 0; // 變化virtual void Step4() = 0; // 變化
};// templateApplication.cpp 應用程序開發人員
class Application : public Library
{
protected:bool Step2 override(){//子類重寫實現}void Step4 override(){// 子類重寫實現}virtual ~Application override();
};// main.cpp 應用程序開發人員
int main()
{Library* pLib = new Application(); // 多態指針,基類類型指針指向派生類對象lib->Run();delete pLib;
}
如果 基類的析構函數不是虛函數,當通過 基類指針 刪除 派生類對象 時,只會調用基類的析構函數,而不會調用派生類的析構函數,可能導致 內存泄漏 或 資源未釋放。
- 早綁定與晚綁定
第一種方式早綁定(晚實現部分調用早實現部分)到第二種方式晚綁定(早實現部分調用晚實現部分)。
模式定義
定義一個操作中的算法的骨架(穩定,如前文中的run()),將一些步驟延遲到子類中(支持子類實現變化)。模板方法模式使得子類可以不改變(即復用)一個算法的結構即可重定義(override重寫)該算法的某些特定步驟。
穩定中有變化,穩定的部分寫為非虛函數,變化的部分寫為虛函數。
設計模式最大的作用是在穩定和變化之間,尋找隔離點,從而分離它們,管理變化。
結構
紅色部分為穩定部分,藍色部分為變化部分。
要點總結
- Template Method模式是一種非常基礎性的設計模式,在面向對象系統中有著大量的應用。它用最簡潔的機制(虛函數的多態性)為很多應用程序框架提供了靈活的擴展點,是代碼復用方面的基本實現結構。
- 除了可以靈活應對子步驟的變化外,“不要調用我,讓我來調用你”的反向控制結構是 模板方法模式 的典型應用。
- 在具體實現方面,被Template Method調用的虛方法可以具有實現,也可以沒有任何實現(抽象方法、純虛方法),但一般推薦將它們設置為protected方法。
來源:極客班——C++設計模式入門