c++模板模式

文章目录

模板模式

什么是模板模式

模板模式(Template Method Pattern)是一种行为设计模式,它定义了一个操作中的算法骨架,将某些步骤的具体实现延迟到子类中。模板模式使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤,从而实现代码复用和扩展性。

使用场景包括:

存在一组相似的操作:当有一组操作拥有相同的算法结构,但是某些步骤的实现细节各不相同的时候,可以使用模板模式来定义这些操作的通用部分,并将变化的部分留给子类去实现。

算法结构固定,部分步骤可变:如果你希望在不改变算法整体结构的前提下,允许子类自由地扩展或修改某些步骤,模板模式是个很好的选择。这样可以保证算法的主体逻辑一致,同时提供必要的定制化能力。

封装算法细节:当需要将算法的实现细节封装起来,仅暴露一个高层接口给调用者使用时,模板模式可以帮助隐藏复杂的内部实现,提高代码的可读性和维护性。

代码复用和扩展:如果你发现有很多重复的代码,只是其中某些小部分逻辑不同,可以考虑使用模板模式提取公共部分到父类中,通过子类化来实现差异化的部分。

示例应用:

UI框架中的渲染流程,如所有页面都有加载、渲染内容、处理事件的基本流程,但具体的内容渲染逻辑由各个页面子类实现。
数据库访问框架中,可能有一个通用的数据库操作流程(连接数据库、发送查询、处理结果、关闭连接),而具体查询的SQL语句则由子类提供。
在框架或库的开发中,如Java并发包中的AbstractQueuedSynchronizer(AQS)使用模板方法模式定义了获取和释放锁的模板方法,具体实现留给子类(如ReentrantLock)。

为什么使用模板模式

在抽象类中统一操作步骤,并规定好接口,让子类实现接口。这样可以把各个具体的, 子类和操作步骤解耦合。你只希望客户端扩展某个特定算法步骤,而不是整个算法或其结构时,可使用模板方法模式。当多个类的算法除一些细微不同之外几乎完全一样时, 你可使用该模式。但其后果就是,只要算法发生变化, 你就可能需要修改所有的类。

模板模式实现步骤

1.提供一个抽象类:负责规定好接口,让子类实现接口,定义一个模板方法

2.提供具体实现子类:实现抽象类的抽象接口即可

示例

cpp 复制代码
#include <iostream>

// 抽象基类,定义模板方法和基本操作
class CoffeeMaker {
public:
    virtual ~CoffeeMaker() {}
    // 模板方法:冲泡咖啡的步骤
    void brewCoffee() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

protected:
    // 基本操作,留给子类实现
    virtual void brew() = 0;
    virtual void addCondiments() = 0;

    // 可能不需要子类重写的辅助方法
    void boilWater() {
        std::cout << "Boiling water" << std::endl;
    }
    void pourInCup() {
        std::cout << "Pouring into cup" << std::endl;
    }

    // 可能需要子类决定的策略方法
    virtual bool customerWantsCondiments() {
        return true;
    }
};

// 具体子类:黑咖啡
class BlackCoffee : public CoffeeMaker {
protected:
    void brew() override {
        std::cout << "Brewing black coffee" << std::endl;
    }
    void addCondiments() override {
        // 黑咖啡不加调料
    }
};

// 具体子类:加糖加奶咖啡
class SugarMilkCoffee : public CoffeeMaker {
protected:
    void brew() override {
        std::cout << "Brewing coffee with sugar and milk" << std::endl;
    }
    void addCondiments() override {
        std::cout << "Adding sugar and milk" << std::endl;
    }
    bool customerWantsCondiments() override {
        return true;
    }
};

int main() {
    CoffeeMaker* maker = new BlackCoffee();
    maker->brewCoffee();
    delete maker;

    std::cout << "\n";

    maker = new SugarMilkCoffee();
    maker->brewCoffee();
    delete maker;

    return 0;
}

在这个例子中,CoffeeMaker类是抽象基类,它定义了冲泡咖啡的基本步骤作为模板方法(brewCoffee),并声明了两个纯虚函数brew和addCondiments作为基本操作,让子类去实现。BlackCoffee和SugarMilkCoffee是具体子类,它们实现了不同的冲泡方式和添加调料的逻辑。通过这种方式,我们可以复用通用的冲泡流程,同时允许子类灵活地改变某些步骤,符合模板方法模式的设计理念。

模板模式优缺点

优点

  • 你可仅允许客户端重写一个大型算法中的特定部分, 使得算法其他部分修改对其所造成的影响减小
  • 你可将重复代码提取到一个超类中

缺点

  • 部分客户端可能会受到算法框架的限制
  • 通过子类抑制默认步骤实现可能会导致违反里氏替换原则
  • 模板方法中的步骤越多, 其维护工作就可能会越困难
相关推荐
兆。3 分钟前
掌握 PyQt5:从零开始的桌面应用开发
开发语言·爬虫·python·qt
尘浮生6 分钟前
Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea
明月看潮生26 分钟前
青少年编程与数学 02-003 Go语言网络编程 15课题、Go语言URL编程
开发语言·网络·青少年编程·golang·编程与数学
南宫理的日知录37 分钟前
99、Python并发编程:多线程的问题、临界资源以及同步机制
开发语言·python·学习·编程学习
逊嘘1 小时前
【Java语言】抽象类与接口
java·开发语言·jvm
van叶~1 小时前
算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝
c++·算法
Half-up1 小时前
C语言心型代码解析
c语言·开发语言
knighthood20011 小时前
解决:ros进行gazebo仿真,rviz没有显示传感器数据
c++·ubuntu·ros
Source.Liu1 小时前
【用Rust写CAD】第二章 第四节 函数
开发语言·rust
monkey_meng1 小时前
【Rust中的迭代器】
开发语言·后端·rust