C++設計模式之Template Method Pattern
- 模式定義
- 核心思想
- 動機(Motivation)
- 結構(Structure)
- 實現步驟
- 應用場景
- 要點總結
模式定義
模式定義: 定義一個操作中的算法的骨架(穩定),而將一些步驟延遲(變化)到子類中。Template Method使得子類可以不改變(復用)一個算法的結構即可重定義(override重寫)該算法的某些特定步驟。
它定義了一個算法的骨架,將某些步驟的具體實現延遲到子類中。該模式通過固定算法結構,允許子類在不改變算法流程的前提下重新定義某些步驟。
核心思想
- 不變流程,可變細節:將算法的公共邏輯封裝在基類中,具體步驟的實現交給子類。
- 避免重復代碼:通過復用基類的模板方法,減少子類中的冗余邏輯。
- 控制擴展點:明確哪些步驟允許子類重寫,哪些必須固定。
動機(Motivation)
- 在軟件構建過程中,對于某一項任務,它常常有穩定的整體操作結構,但各個子步驟卻有很多改變的需求,或者由于固有的原因(比如框架與應用之間的關系)而無法和任務的整體結構同時實現。
- 如何在確定穩定操作結構的前提下,來靈活應對各個子步驟的變化或者晚期實現需求?
結構(Structure)
實現步驟
- 定義抽象基類
基類中聲明模板方法(通常為非虛函數),并定義算法的步驟接口(可以是純虛函數或虛函數)
abstractclass.h
#include<iostream>//定義抽象基類
class AbstractClass {
public:virtual ~AbstractClass() = default;//模板方法:定義算法骨架(不可被子類重寫)void templateMethod() {step1();step2();step3();}
protected://具體步驟(子類必須實現的接口)virtual void step1() = 0; //純虛函數virtual void step2() = 0;virtual void step3() {std::cout << "AbstractClass::step3(默認實現)\n";}
};
- 實現具體子類
子類重寫基類中的步驟方法,提供具體實現
concreteclass.h
#include"abstractclass.h"
class ConcreteClassA :public AbstractClass {
protected:void step1()override {std::cout << "ConcreteClassA:step1 \n";}void step2()override {std::cout << "ConcreteClassA:step2 \n";}//step3使用基類默認實現
};class ConcreteClassB :public AbstractClass {
protected:void step1() override {std::cout << "ConcreteClassB::step1\n";}void step2() override {std::cout << "ConcreteClassB::step2\n";}void step3() override {std::cout << "ConcreteClassB::step3\n";}
};
- 示例調用
main.cpp
#include"concreteclass.h"int main()
{ConcreteClassA objA;objA.templateMethod(); //調用固定流程:step1->step2->step3(默認)ConcreteClassB objB;objB.templateMethod(); //調用流程:step1->step2->step3(自定義)
}
- 輸出結果
ConcreteClassA:step1
ConcreteClassA:step2
AbstractClass::step3(默認實現)
ConcreteClassB::step1
ConcreteClassB::step2
ConcreteClassB::step3
應用場景
- 框架設計:定義框架的流程(如初始化、運行、清理),允許用戶自定義具體步驟,即定義抽象基類
gameframework.h
#pragma once
#include<iostream>
class GameFramework {
public:void run() { //模板方法initialize();mainLoop();shutdown();}protected:virtual void initialize() = 0; //子類實現初始化邏輯virtual void mainLoop() = 0; //子類實現主循環邏輯virtual void shutdown() { //默認實現std::cout << "GameFramework::shutdown \n";}
};
- 數據處理流程:固定數據讀取、處理、保存,允許自定義處理邏輯,即定義抽象基類*
#pragma once
#include<iostream>
class DataProcessor {
public:void process() {//模板方法loadData();analyzeData();saveResult();}protected:virtual void loadData() = 0;virtual void analyzeData() = 0;virtual void saveResult() {std::cout << "Data saved to default path. \n";}
};
要點總結
- Template Method模式是一種非常基礎性的設計模式,在面向對象系統中有著大量的應用。它用最簡潔的機制(虛函數的多態性)為很多應用程序框架提供了靈活的擴展點,是代碼復用方面的基本實現結構。
- 除了可以靈活應對子步驟的變化外,“不要調用我,讓我來調用你”的反向控制結構是Template Method的典型應用。
- 在具體實現方面,被Template Method調用的虛方法可以具有實現,也可以沒有任何實現(抽象方法、純虛方法),但一般推薦將它們設置為protected方法。