1. 程式人生 > >Template Method模板方法模式

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應該不允許子類覆蓋。模板方法屬於行為型模式。比較簡單,也比較常用。