設計模式C++之九(Template Method模板方法模式)

 

模板模式也是相當簡單的一種模式,而且是比較常用的。模板模式是定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。TemplateMethod使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。cbf4life舉的例子是悍馬車模型,更詳細的例子說明可以參考原作者博客:cbf4life.cnblogs.com。這裏只提出C++的設計和實現方法,以方便隨用隨取。

9.1.解釋

main(),客戶

CHummerModel,悍馬模型

CHummerH1Model,悍馬模型型號1

CHummerH2Model,悍馬模型型號2

說明:在CHummerModel聲明Start、Engineboom、Alarm、Stop虛函數,由派生類實現。基類的Run負責組織邏輯,分別調用這幾個派生類實現的函數。

注意:基類中的Run應該禁止派生類覆蓋。

看代碼:

//HummerModel.h

#pragma once
class CHummerModel
{
public:
    CHummerModel(void);
    virtual ~CHummerModel(void);
    void Run();
protected:
    virtual void Start() = 0;
    virtual void Stop() = 0;
    virtual void Alarm() = 0;
    virtual void EngineBoom() = 0;
    virtual bool IsAlarm();
};

//HummerModel.cpp

#include "StdAfx.h"
#include "HummerModel.h"
#include <iostream>
using std::cout;
using std::endl;
CHummerModel::CHummerModel(void)
{
}
CHummerModel::~CHummerModel(void)
{
}
void CHummerModel::Run()
{
    //先發動汽車
    Start();
    //引擎開始轟鳴
    EngineBoom();
    //然後就開始跑了,跑的過程中遇到一條狗擋路,就按喇叭
    if (IsAlarm())
        Alarm();

    //到達目的地就停車
    Stop();
}
bool CHummerModel::IsAlarm()
{
    //鉤子方法,默認喇叭是會響的
    return true;
}

//HummerH1Model.h

#pragma once
#include "hummermodel.h"
class CHummerH1Model :
    public CHummerModel
{
public:
    CHummerH1Model(void);
    ~CHummerH1Model(void);
    void SetAlarm(bool tag);
    void Start();
    void Stop();
    void Alarm();
    void EngineBoom();
    bool IsAlarm();
private:
    bool m_isAlarm;
};
//HummerH1Model.cpp

#include "StdAfx.h"
#include "HummerH1Model.h"
#include <iostream>
using std::cout;
using std::endl;
CHummerH1Model::CHummerH1Model(void)
{
    m_isAlarm = true;
}
CHummerH1Model::~CHummerH1Model(void)
{
}
void CHummerH1Model::Start()
{
    cout << "悍馬H1發動..." << endl;
}
void CHummerH1Model::Stop()
{
    cout << "悍馬H1停車..." << endl;
}
void CHummerH1Model::Alarm()
{
    cout << "悍馬H1鳴笛" << endl;
}
void CHummerH1Model::EngineBoom()
{
    cout << "悍馬H1引擎聲音是這樣...." << endl;
}
bool CHummerH1Model::IsAlarm()
{
    return this->m_isAlarm;
}
void CHummerH1Model::SetAlarm( bool tag )
{
    this->m_isAlarm = tag;
}

//HummerH2Model.h

#pragma once
#include "hummermodel.h"
class CHummerH2Model :
    public CHummerModel
{
public:
    CHummerH2Model(void);
    ~CHummerH2Model(void);
    void Start();
    void Stop();
    void Alarm();
    void EngineBoom();
    bool IsAlarm();
};
//HummerH2Model.cpp

#include "StdAfx.h"
#include "HummerH2Model.h"
#include <iostream>
using std::cout;
using std::endl;
CHummerH2Model::CHummerH2Model(void)
{
}
CHummerH2Model::~CHummerH2Model(void)
{
}
void CHummerH2Model::Start()
{
    cout << "悍馬H2發動..." << endl;
}
void CHummerH2Model::Stop()
{
    cout << "悍馬H2停車..." << endl;
}
void CHummerH2Model::Alarm()
{
    cout << "悍馬H2鳴笛" << endl;
}
void CHummerH2Model::EngineBoom()
{
    cout << "悍馬H2引擎聲音是這樣...." << endl;
}
bool CHummerH2Model::IsAlarm()
{
    return false;
}

//TemplateMethod.cpp

#include "stdafx.h"
#include "HummerModel.h"
#include "HummerH1Model.h"
#include "HummerH2Model.h"
#include <crtdbg.h>
int _tmain(int argc, _TCHAR* argv[])
{
    //客戶開着H1型號,出去遛彎了
    CHummerModel *ph1 = new CHummerH1Model();
    ph1->Run();
    delete ph1;

    //客戶開H2型號,出去玩耍了
    CHummerModel *ph2 = new CHummerH2Model();
    ph2->Run();
    delete ph2;

    //客戶開着H1型號,出去遛彎了,並且不讓喇叭響
    CHummerH1Model *ph11 = new CHummerH1Model();
    ph11->SetAlarm(false);
    ph11->Run();
    delete ph11;

    _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
    _CrtDumpMemoryLeaks();
    return 0;
}

由基類的Run來實現基本固定的邏輯,而把不同的部分封裝在子類裏。Run應該不允許子類覆蓋。模板方法屬於行爲型模式。比較簡單,也比較常用。

發佈了8 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章