C++设计模式——Template Method模板方法模式

一,模板方法模式的定义

模板方法模式是一种行为型设计模式,它先定义了一个算法的大致框架,然后将算法的具体实现步骤分解到多个子类中。

模板方法模式为算法设计了一个抽象的模板,算法的具体代码细节由子类来实现,从而使算法在整体上结构稳定,但是又能被灵活修改和扩展。

模板方法模式在现实生活中的抽象实例:

美食烹饪:烹饪包含很多步骤,包括选食材、切菜、煮熟等,但是每道菜的食材和烹饪时间会不同,此时可以将烹饪的通用步骤抽象为模板方法,具体细节由不同的菜来决定。

游戏开发:游戏中的角色有移动、攻击、防御等共同行为,将共同行为抽象为模板方法,具体细节根据不同的游戏角色来单独实现。

车辆生产:车辆生产流程中有组装、装配、涂漆等共同步骤,将共同步骤抽象为模板方法,具体的生产步骤根据不同的车型来改变。

例如:打工人作息模板

二,模板方法模式的结构

模板方法模式主要包含以下组件:
1.抽象类(AbstractClass):
定了算法的大致框架,里面包含了一个模板方法(templateMethod)和多个基本操作方法(execute1, execute2),模板方法定义了算法的实现步骤,而算法的实现步骤由这些基本操作组成。抽象类只定义了模板方法和基本操作流程,不提供具体的代码实现。
2.具体类(ConcreteClass):
是抽象类的具体实现,里面实现了抽象类定义的基本操作方法(execute1, execute2),不同的具体类对基本操作方法的实现细节可能有差异。
组件之间的工作步骤如下:
1.在抽象类中定义一个模板方法(templateMethod),将模板方法作为算法的大致框架。
2.在抽象类中声明若干个基本操作方法(execute1, execute2),将这些方法在模板方法中按特定顺序调用,作为算法的执行流程。
3.在不同的具体类中,按照业务分别用代码实现基本操作方法。
对应UML类图:

三,模板方法模式代码样例

以下代码的结构和上述描述基本一致

cpp 复制代码
#include <iostream>

class AbstractClass {
public:
   //模板方法
    void templateMethod() {
       //算法步骤
        execute1();
        execute2();
    }
protected:
      //基本操作方法
    virtual void execute1() = 0;
    virtual void execute2() = 0;
};

class ConcreteClassA : public AbstractClass {
protected:
    void execute1() override {
        std::cout << "ConcreteClassA: execute1 called" << std::endl;
    }
    void execute2() override {
        std::cout << "ConcreteClassA: execute2 called" << std::endl;
    }
};

class ConcreteClassB : public AbstractClass {
protected:
    void execute1() override {
        std::cout << "ConcreteClassB: execute1 called" << std::endl;
    }
    void execute2() override {
        std::cout << "ConcreteClassB: execute2 called" << std::endl;
    }
};

int main() {
    AbstractClass* classA = new ConcreteClassA();
    classA->templateMethod();
    AbstractClass* classB = new ConcreteClassB();
    classB->templateMethod();
    delete classA;
    delete classB;
    return 0;
}

运行结果:

bash 复制代码
ConcreteClassA: execute1 called
ConcreteClassA: execute2 called
ConcreteClassB: execute1 called
ConcreteClassB: execute2 called

四,模板方法模式的应用场景

软件框架开发:开发复杂的框架时先定义好基础流程,然后在子类中分别实现具体细节。

编译器开发:在编译器中先定义基本的步骤如词法分析、语法分析等,然后在子类中实现具体的解析步骤。

驱动程序开发:将程序的初始化、数据读写、通信等基础操作抽象为模板方法,然后根据不同的设备参数实现具体操作。

五,模板方法模式的优缺点

模板方法模式的优点:

使代码更加简洁,具体细节交给子类实现,避免了重复代码。

模板方法定义以后,后面只需要重点维护子类的代码实现,系统可扩展性和灵活性很强。

系统稳定性强,无论后续如何修改子类,算法的基本流程不变。

模板方法模式的缺点:

子类太多容易导致继承的过度滥用。

系统结构复杂,增加了代码维护难度。

如果有些基本操作没有提供默认的行为,可能导致功能出错。

六,代码实战

基于模板方法模式实现的模拟汽车生产

cpp 复制代码
#include <iostream>

class VehicleTemplate {
public:
    void buildVehicle() {
        assembleBody();
        installEngine();
        addWheels();
        std::cout<<"Vehicle is ready!\n";
    }
    virtual void assembleBody() = 0;
    virtual void installEngine() = 0;
    virtual void addWheels() = 0;
};

class Car: public VehicleTemplate {
public:
    void assembleBody() override {
        std::cout<<"Assembling car body.\n";
    }
    void installEngine() override {
        std::cout<<"Installing car engine.\n";
    }
    void addWheels() override {
        std::cout<<"Adding 4 wheels to the car.\n ";
    }
};

class Motorcycle: public VehicleTemplate {
public:
    void assembleBody() override {
        std::cout<<"Assembling motorcycle frame.\n";
    }
    void installEngine() override {
        std::cout<<"Installing motorcycle engine.\n";
    }
    void addWheels() override {
        std::cout<<"Adding 2 wheels to the motorcycle.\n ";
    }
};

int main() {
    std::cout<<"Building a Car : \n";
    Car car;
    car.buildVehicle();
    std::cout<<"\nBuilding a Motorcycle : \n";
    Motorcycle motorcycle;
    motorcycle.buildVehicle();
    return 0;
}

运行结果:

bash 复制代码
Building a Car :
Assembling car body.
Installing car engine.
Adding 4 wheels to the car.
Vehicle is ready!


Building a Motorcycle :
Assembling motorcycle frame.
Installing motorcycle engine.
Adding 2 wheels to the motorcycle.
Vehicle is ready!

七,参考阅读

https://www.geeksforgeeks.org/template-method-design-pattern-c-design-patterns/

https://sourcemaking.com/design_patterns/template_method

https://www.geeksforgeeks.org/template-method-design-pattern/

https://www.modernescpp.com/index.php/the-template-method/

相关推荐
jieyucx9 小时前
Go语言深度解剖:Map扩容机制全解析(增量扩容+等量扩容+渐进式迁移)
开发语言·后端·golang·map·扩容策略
顾温9 小时前
default——C#/C++
java·c++·c#
凉茶钱9 小时前
【c语言】动态内存管理:malloc,calloc,realloc,柔性数组
c语言·c++·vscode·柔性数组
脏脏a9 小时前
【C++模版】泛型编程:代码复用的终极利器
开发语言·c++·c++模版
island13149 小时前
【C++仿Muduo库#3】Server 服务器模块实现上
服务器·开发语言·c++
散峰而望9 小时前
【算法竞赛】C/C++ 的输入输出你真的玩会了吗?
c语言·开发语言·数据结构·c++·算法·github
小龙报9 小时前
【C语言】内存里的 “数字变形记”:整数三码、大小端与浮点数存储真相
c语言·开发语言·c++·创业创新·学习方法·visual studio
深耕AI9 小时前
【VS Code避坑指南】点击Python图标提示“没有Python环境”,选择安装uv后这堆输出到底是什么意思?
开发语言·python·uv
刃神太酷啦9 小时前
扒透 STL 底层!map/set 如何封装红黑树?迭代器逻辑 + 键值限制全手撕----《Hello C++ Wrold!》(23)--(C/C++)
java·c语言·javascript·数据结构·c++·算法·leetcode
2301_789015629 小时前
C++:继承
c语言·开发语言·c++