前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++设计模式 - 模板方法模式

C++设计模式 - 模板方法模式

作者头像
开源519
发布2022-12-01 16:07:49
3940
发布2022-12-01 16:07:49
举报
文章被收录于专栏:开源519

前言

或许当下的我们正经历着事与愿违,努力了,却什么也改变不了。眼下的困局很难,可以选择躺平,但为心中的愿景再努力一把应该更加振奋人心! 不要因为眼前的泥泞而畏手畏脚,不要因为前路的未知而愁绪如麻。时间匆匆,总该为短暂的一生留下些难忘的痕迹。青年不就是拿汗水拼搏的阶段吗?以梦为马,不负韶华。流年笑掷,余生可期。青年节快乐!

模板方法

❝模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 ❞

模板方法模式利用C++多态特征,在父类定义一套结构流程,其中通用部分在父类实现,子类继承父类实现差异性的接口。

意义

模板方法模式是比较实用的一种设计模式,将不变部分的流程和接口在父类实现,变化部分的接口预留出来交由子类实现。如此,有利于代码的复用性、可扩展性。

应用场景

一位头痛和一位胃疼的病人去医院看病。

分析

现在有两位不同症状的病人去看病,可以自实现两套去不同科室的流程。假如10个、20个不同症状的病人,按照这种设计,代码工作量大不说还会存在大量的重复逻辑代码。遇到这种重复代码,就要想办法抽象。

  1. 先抽象出看病流程,所有病人去医院看病的流程都是一致的。无非是: 出示健康码、填表、挂号、医生面诊和缴费。
  2. 其中不同症状的病人看病流程一致,至于每个环节的内容是有些差异的。可交由子类多态实现。

类图

模板方法类图

  • CSeeDoctorTempateMethod: 看医生基类。实现通用的看病流程,声明必要的接口。
  • CTreatStomach: 看胃病子类。继承看病流程,根据自身实现具体接口。
  • CTreatHeadache: 看头痛子类。继承看病流程,根据自身实现具体接口。

源码实现

「编程环境」

  1. 编译环境: Linux环境
  2. 语言: C++语言
  3. 编译命令: make

「工程结构」

代码语言:javascript
复制
TemplateMethod/
├── main.cc
├── Makefile
├── see_doctor.cc
└── see_doctor.h
  • see_doctor: 看医生具体的逻辑业务
  • main.cc: 客户端代码,程序入口
  • Makefile: 编译工具

「看医生基类」:

代码语言:javascript
复制
class CSeeDoctorTemplate
{
public:
    CSeeDoctorTemplate();

    ~CSeeDoctorTemplate();

    // 看病流程
    virtual void StartProcess() final;

    // 展示健康码
    virtual void ShowHealthCode();

    // 填写登记表
    virtual void FillTable() = 0;

    // 挂号
    virtual void Register() = 0;

    // 医生面诊
    virtual void SeeDoctor();

    // 付款
    virtual void Pay();

public:
    float mCost;
};

「通用流程接口实现」:

代码语言:javascript
复制
// 看病流程
void CSeeDoctorTemplate::StartProcess()
{
    this->ShowHealthCode();
    this->FillTable();
    this->Register();
    this->SeeDoctor();
    this->Pay();
}

此基类定义出通用的流程和接口,子类只需要继承基类实现具体的接口即可。


看胃病

代码语言:javascript
复制
class CTreatStomach : public CSeeDoctorTemplate
{
public:
    CTreatStomach();

    ~CTreatStomach();

    void FillTable();

    void Register();

    void SeeDoctor();
};

CTreatStomach继承CSeeDoctorTemplate,并实现具体有差异的几个接口即可。

客户端代码

代码语言:javascript
复制
int main(int argc, char *argv[])
{
    shared_ptr<CSeeDoctorTemplate> p1(new CTreatStomach);
    p1->StartProcess();

    MAIN_LOG("\n\n");

    shared_ptr<CSeeDoctorTemplate> p2(new CTreatHeadache);
    p2->StartProcess();

    return 0;
}

测试效果

代码语言:javascript
复制
-------- Treat Stomach --------
Show health code! 
Fill table: Stomach.
Register Internal Medicine.
See physician internist.
Pay the medical bills 230.90¥.


-------- Treat Headache --------
Show health code! 
Fill table: Headache.
Register Surgery.
See surgeon.
Pay the medical bills 82.70¥.

总结

  • 当希望客户端扩展某个特定算法步骤, 而不是整个算法或其结构时, 可使用模板方法模式。 模板方法将整个算法转换为一系列独立的步骤, 以便子类能对其进行扩展, 同时还可让超类中所定义的结构保持完整。
  • 当多个类的算法除一些细微不同之外几乎完全一样时, 可使用该模式。但其后果就是, 只要算法发生变化, 你就可能需要修改所有的类。 在将算法转换为模板方法时, 可将相似的实现步骤提取到超类中以去除重复代码。子类间各不同的代码可继续保留在子类中。
  • 本例程为了方便没有将基类独立出来,实际应用应将此放在独立的头文件中,方便引用。

最后

用心感悟,认真记录,写好每一篇文章,分享每一框干货。

更多文章内容包括但不限于C/C++、Linux、开发常用神器等,可进入“开源519公众号”聊天界面输入“文章目录” 或者 菜单栏选择“文章目录”查看。公众号后台聊天框输入本文标题,在线查看源码。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源519 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 模板方法
    • 意义
      • 应用场景
        • 分析
          • 类图
            • 源码实现
              • 看胃病
                • 客户端代码
                  • 测试效果
                    • 总结
                      • 最后
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档