《編碼規範和測試方法——C/C++版》作業 ·006——設計模式 · 模板方法

一、設計模式-模板方法

1、簡單介紹

簡單來說,就是先在父類FF中定義好一個函數AA,然後這個函數AA代表了一個操作MM,函數AA的內部調用了若干個已經實現的函數BiB_i、未實現的函數CiC_iBiB_iCiC_i這些函數在函數AA中的執行流程構成了函數AA的整體框架,其中

  • 函數AA象徵了操作MM的整體流程
  • 函數BiB_i象徵了操作MM中既定的步驟,所有不同主體的操作MM中的這些步驟都相同
  • 函數CiC_i象徵了操作MM中未定的步驟,存在不同主體的操作MM中的這些步驟不相同

這樣的設計下,我們可以根據不同的場景來設計子類SiS_i的函數CiC_i的具體內容。父類FF往往是抽象類。


模板方法的整體思想是,對於某個操作,先在父類中定義好其算法的整體框架,然後將框架中的步驟延遲到子類裏面去實現。


這樣做的好處是,算法的整體框架已經定下來了,對於相似操作的不同步驟可以在子類中給出具體的實現。

  • 在子類中不需要重寫出共同的重複步驟,代碼複用性強
  • 在子類中也改變不了整體框架(或者說是運行流程),整體結構性強。

2、框架演示

UML圖示
UML-1

代碼

// 抽象父類——F
class F
{
public:
	void process_whole()  // 整體的操作
	{
		common_step_1();      // 共同步驟1
		common_step_2();      // 共同步驟2
		especial_step_1();    // 【待實現】不同步驟1
		especial_step_2();    // 【待實現】不同步驟2
		common_step_etc();    // 共同步驟...
		especial_step_etc();  // 【待實現】不同步驟...
		especial_step_m();    // 【待實現】不同步驟m
		common_step_n();      // 共同步驟n
	}
protected:
	virtual void especial_step_1() = 0;    // 不同步驟1
	virtual void especial_step_2() = 0;    // 不同步驟2
	virtual void especial_step_etc() = 0;  // 不同步驟...
	virtual void especial_step_m() = 0;    // 不同步驟m
private:
	void common_step_1() {  }    // 共同步驟1
	void common_step_2() {  }    // 共同步驟2
	void common_step_etc() {  }  // 共同步驟...
	void common_step_n() {  }    // 共同步驟n
};

// 實現子類——S1
class S1 : public F
{
	virtual void especial_step_1()
	{
		// 【S1具體實現】不同步驟1
	}
	virtual void especial_step_2() = 0
	{
		// 【S1具體實現】不同步驟2
	}
	virtual void especial_step_etc() = 0
	{
		// 【S1具體實現】不同步驟...
	}
	virtual void especial_step_m() = 0
	{
		// 【S1具體實現】不同步驟m
	}
};

// 實現子類——S2
class S2 : public F
{
	virtual void especial_step_1()
	{
		// 【S2具體實現】不同步驟1
	}
	virtual void especial_step_2() = 0
	{
		// 【S2具體實現】不同步驟2
	}
	virtual void especial_step_etc() = 0
	{
		// 【S2具體實現】不同步驟...
	}
	virtual void especial_step_m() = 0
	{
		// 【S2具體實現】不同步驟m
	}
};

3、實際案例

案例:


現在設計一個父類爲動物飼養員AnimalRaiser,有一個函數feed功能是爲動物餵食,餵食的過程分爲:

  1. 拿出飯碗
  2. 放上食物
  3. 等待動物食用完畢
  4. 回收飯碗洗乾淨

由於每個動物食用的食物不同,需要根據動物的種類餵食不同的飼料,比如給狗狗餵食排骨,給貓咪餵食清蒸魚。(假設其他步驟對所有動物均相同)


另外設計兩個類——狗狗飼養員DogRaiser、貓咪飼養員CatRaiser.

UML圖示
UML-2

AnimalRaiser類

  • AnimalRaiser.h

    #ifndef ANIMALRAISER_H
    #define ANIMALRAISER_H
    
    class AnimalRaiser
    {
    public:
    	AnimalRaiser();
    	virtual ~AnimalRaiser();
    
    	void feed();
    protected:
    	virtual void push_food() = 0;
    private:
    	void prepare_bowl();
    	void wait_eat();
    	void clear_bowl();
    };
    
    #endif // !ANIMALRAISER_H
    
  • AnimalRaiser.cpp

    #include "pch.h"
    
    #include "AnimalRaiser.h"
    #include <iostream>
    
    using namespace std;
    
    AnimalRaiser::AnimalRaiser()
    {
    }
    
    AnimalRaiser::~AnimalRaiser()
    {
    }
    
    void AnimalRaiser::feed()
    {
    	prepare_bowl();
    	push_food();
    	wait_eat();
    	clear_bowl();
    }
    
    void AnimalRaiser::prepare_bowl()
    {
    	cout << "正在準備飯碗..." << endl;
    }
    
    void AnimalRaiser::wait_eat()
    {
    	cout << "正在等待食用完畢..." << endl;
    }
    
    void AnimalRaiser::clear_bowl()
    {
    	cout << "正在回收飯碗並清洗..." << endl;
    }
    

CatRaiser類

  • CatRaiser.h

    #include "AnimalRaiser.h"
    
    #ifndef CATRAISER_H
    #define CATRAISER_H
    
    class CatRaiser :
    	public AnimalRaiser
    {
    public:
    	CatRaiser();
    	virtual ~CatRaiser();
    protected:
    	virtual void push_food();
    };
    
    #endif // !CATRAISER_H
    
  • CatRaiser.cpp

    #include "pch.h"
    
    #include "CatRaiser.h"
    #include <iostream>
    
    using namespace std;
    
    CatRaiser::CatRaiser()
    {
    }
    
    CatRaiser::~CatRaiser()
    {
    }
    
    void CatRaiser::push_food()
    {
    	cout << "正在往碗裏放上貓咪最愛吃的清蒸魚..." << endl;
    }
    

DogRaiser類

  • DogRaiser.h

    #include "AnimalRaiser.h"
    
    #ifndef DOGRAISER_H
    #define DOGRAISER_H
    
    class DogRaiser :
    	public AnimalRaiser
    {
    public:
    	DogRaiser();
    	virtual ~DogRaiser();
    protected:
    	virtual void push_food();
    };
    
    #endif // !DOGRAISER_H
    
  • DogRaiser.cpp

    #include "pch.h"
    
    #include "DogRaiser.h"
    #include <iostream>
    
    using namespace std;
    
    DogRaiser::DogRaiser()
    {
    }
    
    DogRaiser::~DogRaiser()
    {
    }
    
    void DogRaiser::push_food()
    {
    	cout << "正在往碗裏放上狗狗最愛吃的排骨..." << endl;
    }
    

Main

  • Main.cpp
    #include "pch.h"
    
    #include "CatRaiser.h"
    #include "DogRaiser.h"
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    	CatRaiser cr1;
    	DogRaiser dr1;
    
    	AnimalRaiser* arp;
    	
    	arp = &cr1;
    	arp->feed();
    
    	cout << "------------------------------------" << endl;
    
    	arp = &dr1;
    	arp->feed();
    
    	return 0;
    }
    

執行結果

正在準備飯碗...
正在往碗裏放上貓咪最愛吃的清蒸魚...
正在等待食用完畢...
正在回收飯碗並清洗...
------------------------------------
正在準備飯碗...
正在往碗裏放上狗狗最愛吃的排骨...
正在等待食用完畢...
正在回收飯碗並清洗...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章