【嵌入式c++】设计模式之模板模式(Template Method)

Template Method

动机(Motivation)

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

模式定义

定义一个操作中的算法的骨架 (稳定) ,而将一些步骤延迟 (变化) 到子类中。
Template Method使得子类可以不改变(复用)一个算法的结构即可重定义(override 重写)该算法的
某些特定步骤。
——《 设计模式》 GoF

要点总结

  • Template Method模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)
    为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
  • 除了可以灵活应对子步骤的变化外, “不要调用我,让我来调用你” 的反向控制结构是Template Method的典型应用。
  • 在具体实现方面,被Template Method调用的虚方法可以具有实现,也可以没有任何实现(抽象方法、纯虚方法),但一般推荐将它们设置为protected方法。

代码结构


├── build.sh
├── clearBuild.sh
├── CMakeLists.txt
├── src
├── exam1
│ ├── include
│ │ ├── CaffeineBeverage.hpp
│ │ ├── Coffee.hpp
│ │ └── Tea.hpp
│ └── main.cpp
└── exam2
├── examStu.cpp
├── include
│ └── examStu.h
└── main.cpp

源码例子1

CaffeineBeverage.hpp

#ifndef CAFFEINEBEVERAGE_HPP
#define CAFFEINEBEVERAGE_HPP

#include <iostream>

class CaffeineBeverage {
    
    
public:
    virtual ~CaffeineBeverage(){
    
    }

    void prepareRecipe() {
    
    
        boilWater();
        brew();
        pourInCup();
        if(customerWantsCondiments())
            addCondiments();
    }

    virtual void brew() = 0;
    virtual void addCondiments() = 0;

    void boilWater() {
    
    
        std::cout << "Boiling water\n";
    }

    void pourInCup() {
    
    
        std::cout << "Pouring into cup\n";
    }

    virtual bool customerWantsCondiments() {
    
    
        return true;
    }
};


#endif

Coffee.hpp

#ifndef COFFEE_HPP
#define COFFEE_HPP

#include "CaffeineBeverage.hpp"

#include <iostream>

class Coffee : public CaffeineBeverage {
    
    
public:
    ~Coffee(){
    
    }

    void brew() {
    
    
        std::cout << "Dripping Coffee through filter\n";
    }

    void addCondiments() {
    
    
        std::cout << "Adding Sugar and Milk\n";
    }

    bool customerWantsCondiments() {
    
    
        char c;
        std::cout << "Do you want to add condiments?\n";
        std::cin >> c;

        if(c == 'y')
            return true;
        else
            return false;
    }
};


#endif

Tea.hpp

#ifndef TEA_HPP
#define TEA_HPP

#include "CaffeineBeverage.hpp"

#include <iostream>

class Tea : public CaffeineBeverage {
    
    
public:
    ~Tea(){
    
    }

    void brew() {
    
    
        std::cout << "Steeping the tea\n";
    }

    void addCondiments() {
    
    
        std::cout << "Adding Lemon\n";
    }

    bool customerWantsCondiments()
    {
    
    
        char c;
        std::cout << "Do you want to add condiments?\n";
        std::cin >> c;

        if (c == 'y')
            return true;
        else
            return false;
    }
};

#endif

main.cpp

#include "Tea.hpp"
#include "Coffee.hpp"

int main() {
    
    
    Tea* tea = new Tea();
    Coffee* coffee = new Coffee();

    std::cout << "\nMaking tea...\n";
    tea->prepareRecipe();

    std::cout << "\nMaking coffee...\n";
    coffee->prepareRecipe();

    delete tea;
    delete coffee;
}

源码例子2

examStu.h

#ifndef _EXANSTU__
#define _EXANSTU__

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

class FileOperation
{
    
    
public:
    FileOperation()=default;
    ~FileOperation(){
    
    cout << "~FileOperation"<<endl;};
    void DownloadFiles()
    {
    
    
          if (!DownloadFileBegin()) return ;
          if (!DownloadFileProcess()) return ;
          if (!DownloadFileEnd()) return ;
    }
protected:
    virtual bool DownloadFileBegin( ){
    
     return true;}
    virtual bool DownloadFileProcess() {
    
     return true;}
    virtual bool DownloadFileEnd(){
    
     return true;}

private:

};


class WebDownLoadFiles :public  FileOperation
{
    
    
public:   
    WebDownLoadFiles()=default;
    ~WebDownLoadFiles(){
    
    cout << "~WebDownLoadFiles"<<endl;}

protected:
    bool DownloadFileBegin() override {
    
     cout << "WebDownloadFileBegin"<<endl; return true; }
    bool DownloadFileProcess() override {
    
    cout << "WebDownloadFileProcess"<<endl;  return true; }
    bool DownloadFileEnd() override {
    
    cout << "WebDownloadFileEnd"<<endl;  return true; }


};

class PhoneDownLoadFiles :public  FileOperation
{
    
    
public:   
    PhoneDownLoadFiles()=default;
    ~PhoneDownLoadFiles(){
    
    cout << "~PhoneDownLoadFiles"<<endl;}

protected:
    bool DownloadFileBegin( ) override {
    
     cout << "PhoneDownloadFileBegin"<<endl; return true; }
    bool DownloadFileProcess( ) override {
    
    cout << "PhoneDownloadFileBegin"<<endl;  return true; }
    bool DownloadFileEnd( ) override {
    
    cout << "PhoneDownloadFileBegin"<<endl;   return true;}


};

#endif

main.cpp

#include <iostream>
#include <string>
#include <memory>

#include "examStu.h"

using namespace std;


int main()
{
    
    

    std::shared_ptr<FileOperation> pWebDownLoadFiles = std::make_shared<WebDownLoadFiles>();
    pWebDownLoadFiles->DownloadFiles();

    std::shared_ptr<FileOperation> pPhoneDownLoadFiles = std::make_shared<PhoneDownLoadFiles>();
    pPhoneDownLoadFiles->DownloadFiles();

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_15555275/article/details/109468601