【C++设计模式之Template Method Pattern】

C++设计模式之Template Method Pattern


模式定义

模式定义: 定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。Template Method使得子类可以不改变(复用)一个算法的结构即可重定义(override重写)该算法的某些特定步骤。
它定义了一个算法的骨架,将某些步骤的具体实现延迟到子类中。该模式通过固定算法结构,允许子类在不改变算法流程的前提下重新定义某些步骤。

核心思想

  • 不变流程,可变细节:将算法的公共逻辑封装在基类中,具体步骤的实现交给子类。
  • 避免重复代码:通过复用基类的模板方法,减少子类中的冗余逻辑。
  • 控制扩展点:明确哪些步骤允许子类重写,哪些必须固定。

动机(Motivation)

  • 在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
  • 如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?

结构(Structure)

实现步骤

  1. 定义抽象基类

基类中声明模板方法(通常为非虚函数),并定义算法的步骤接口(可以是纯虚函数或虚函数)

abstractclass.h

cpp 复制代码
#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";
	}
};
  1. 实现具体子类

子类重写基类中的步骤方法,提供具体实现

concreteclass.h

cpp 复制代码
#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";
	}
};
  1. 示例调用
    main.cpp
cpp 复制代码
#include"concreteclass.h"

int main()
{
	ConcreteClassA objA;
	objA.templateMethod();   //调用固定流程:step1->step2->step3(默认)
	ConcreteClassB objB;
	objB.templateMethod();   //调用流程:step1->step2->step3(自定义)
}
  1. 输出结果
cpp 复制代码
ConcreteClassA:step1
ConcreteClassA:step2
AbstractClass::step3(默认实现)
ConcreteClassB::step1
ConcreteClassB::step2
ConcreteClassB::step3

应用场景

  1. 框架设计 :定义框架的流程(如初始化、运行、清理),允许用户自定义具体步骤,即定义抽象基类

gameframework.h

cpp 复制代码
#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";
	}
};
  1. 数据处理流程 :固定数据读取、处理、保存,允许自定义处理逻辑,即定义抽象基类*
cpp 复制代码
#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方法。
相关推荐
静水流深_沧海一粟18 小时前
04 | 别再写几十个参数的构造函数了——建造者模式
设计模式
StarkCoder18 小时前
从UIKit到SwiftUI的迁移感悟:数据驱动的革命
设计模式
阿星AI工作室1 天前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
_哆啦A梦2 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
阿闽ooo5 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式
小米4965 天前
js设计模式 --- 工厂模式
设计模式
逆境不可逃5 天前
【从零入门23种设计模式08】结构型之组合模式(含电商业务场景)
线性代数·算法·设计模式·职场和发展·矩阵·组合模式
驴儿响叮当20105 天前
设计模式之状态模式
设计模式·状态模式
电子科技圈5 天前
XMOS推动智能音频等媒体处理技术从嵌入式系统转向全新边缘计算
人工智能·mcu·物联网·设计模式·音视频·边缘计算·iot
徐先生 @_@|||6 天前
安装依赖三方exe/msi的软件设计模式
设计模式