1. 程式人生 > >Strategy模式和Template Method模式的異同淺析

Strategy模式和Template Method模式的異同淺析

一、Strategy模式 1. 特點說明:
  • 定義一系列的演算法,把它們一個個封裝起來,並且使它們可相互替換。
  • 適用場景:
    • 許多相關的類僅僅是行為有異。“策略”提供了一種用多個行為中的一個行為來配置一個類的方法。
    • 需要使用一個演算法的不同變體。
    • 演算法使用客戶不應該知道的資料。使用策略模式避免暴露覆雜的、與演算法相關的資料結構。
    • 一個類定義了多種行為,並且這些行為在這個類的操作中以多個條件語句的形式出現。將相關的條件分支移入他們各自的Strategy類中以代替這些條件語句。
2. 基本的實現程式碼


/** 
 * 體操策略模式基類. 
 */ 
class StrategyGym 
{ 
public: 
    StrategyGym(); 
    virtual ~StrategyGym(); 
    virtual void DoGym() = 0; //純虛擬函式 
}; 

//--------體操基類實現-------- 
StrategyGym::StrategyGym() 
{ 
} 
StrategyGym::~StrategyGym() 
{ 
    cout << "~StrategyGym....."<<endl;
}

/** 
 * 眼保健操策略類. 
 */ 
class StrategyEyeGym : public StrategyGym 
{ 
public: 
	StrategyEyeGym(); 
	virtual ~StrategyEyeGym(); 
	void DoGym(); 
}; 

//--------眼保健操類-------- 
StrategyEyeGym::StrategyEyeGym() 
{ 
} 
StrategyEyeGym::~StrategyEyeGym() 
{ 
    cout << "打完收工....." << endl; 
} 
//做啥捏? 眼保健操 
void StrategyEyeGym::DoGym() 
{ 
    cout << "做眼保健操1->4節." << endl; 
} 
/** 
 * 廣播體操策略類. 
 */ 
class StrategyBroadcastGym : 
      public StrategyGym 
{ 
public: 
    StrategyBroadcastGym(); 
    virtual ~StrategyBroadcastGym(); 
    void DoGym(); 
}; 
//--------廣播體操-------- 
StrategyBroadcastGym::StrategyBroadcastGym() 
{ 
} 
StrategyBroadcastGym::~StrategyBroadcastGym() 
{ 
    cout << "廣播體操,做完....." << endl; 
} 
void StrategyBroadcastGym::DoGym() 
{ 
    cout << "做廣播體操1->8節." << endl; 
} 

/** 
 * 策略使用類 
 */ 
class Context 
{ 
public: 
    Context(StrategyGym* stg); 
    ~Context(); 
    void DoAction(); 
private: 
    StrategyGym* _stg; //體操的基類指標 
}; 
//--------策略使用者.-------- 
Context::Context(StrategyGym* stg) 
{ 
    _stg = stg; 
} 
Context::~Context() 
{ 
    if (_stg != NULL) 
    { 
        delete _stg; 
    } 
} 
void Context::DoAction() 
{ 
/* 一旦選擇一個演算法, 就完全切換了整個演算法.
 一個演算法與另外一個演算法, 沒有什麼共同的地方.*/ 
    _stg->DoGym();
} 

上述程式碼類圖表示為:


呼叫者的程式碼:

//策略模式例子 
//眼保健操 
StrategyGym* sEye = new StrategyEyeGym(); 
Context contextEye(sEye); 
contextEye.DoAction(); 
//廣播體操 
StrategyGym* sBroad = new StrategyBroadcastGym(); 
Context contestBroad(sBroad); 
contestBroad.DoAction(); 
3. 策略模式淺析:
  • 優點
    • Strategy類層次定義了一系列的可供重用的演算法或行為;
    • 消除條件語句;
    • Strategy提供相同行為的不同實現;
  • 缺點
    • 客戶必須瞭解不同的Strategy;
    • Strategy和Context之間的通訊開銷;
    • 增加了物件的數目;
二、Template Method模式

1.  特點說明

  • 定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。
  • 使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。
  • 一次性實現一個演算法的不變的部分,並將可變的行為留給子類來實現。
  • 各子類中公共的行為被提取出來並集中到一個公共父類中,避免程式碼重複。
  • 注:Template Method模式和C++模板一點關係都沒有

2. 基本程式碼實現



class TemplateMethod 
{ 
public: 
    virtual ~TemplateMethod(); 
    void DoGym(); //對外部的介面 
protected: 
    //實際需要呼叫的虛擬函式, 需要派生類實現 
    virtual void Section1st() = 0; 
    virtual void Section2nd() = 0; 
    virtual void Section3rd() = 0; 
    virtual void Section4th() = 0; 
    virtual void Section5th() = 0; 
    virtual void Section6th() = 0; 
    virtual void Section7th() = 0; 
    virtual void Section8th() = 0; 
    TemplateMethod();
}; 
TemplateMethod::TemplateMethod() 
{ 
} 
TemplateMethod::~TemplateMethod() 
{ 
} 
/* 對外的介面函式, 呼叫實際的處理函式, 
這樣, 如果派生類的實現有改動,介面是不需要改動的. 
把公共的部分, 放在介面中, 這是外部使用這個演算法時, 不變的部分, 
比如一個演算法的步驟. 
*/ 
void TemplateMethod::DoGym() 
{ 
    /* 就目前而言, 不管哪一套廣播體操, 一般是8節, 這8節的具體做法可能不一樣,就需要派生類具體實現了.但整個廣播體操的整體架構是一樣的, 都是8節, 都是從第1節做到第8節.*/ 
    Section1st(); 
    Section2nd(); 
    Section3rd(); 
    Section4th(); 
    Section5th(); 
    Section6th(); 
    Section7th(); 
    Section8th();
} 

//第8套廣播體操 
class BroadcastGymEighth : public TemplateMethod 
{ 
public: 
    BroadcastGymEighth(); 
    ~BroadcastGymEighth(); 
protected: 
    void Section1st(); 
    void Section2nd(); 
    void Section3rd(); 
    void Section4th(); 
    void Section5th(); 
    void Section6th(); 
    void Section7th(); 
    void Section8th();
}; 


//第8套廣播體操 
BroadcastGymEighth::BroadcastGymEighth() 
{ } 
BroadcastGymEighth::~BroadcastGymEighth() 
{} 
void BroadcastGymEighth::Section1st() 
{ 
    cout << "第八套廣播體操, 第1節." << endl; 
} 
void BroadcastGymEighth::Section2nd() 
{ 
    cout << "第八套廣播體操, 第2節." << endl; 
} 
void BroadcastGymEighth::Section3rd() 
{ 
    cout << "第八套廣播體操, 第3節." << endl; 
} 
void BroadcastGymEighth::Section4th() 
{ 
    cout << "第八套廣播體操, 第4節." << endl; 
} 
void BroadcastGymEighth::Section5th() 
{ 
    cout << "第八套廣播體操, 第5節." << endl; 
} 
void BroadcastGymEighth::Section6th() 
{ 
    cout << "第八套廣播體操, 第6節." << endl; 
} 
void BroadcastGymEighth::Section7th() 
{ 
    cout << "第八套廣播體操, 第7節." << endl; 
} 
void BroadcastGymEighth::Section8th() 
{ 
    cout << "第八套廣播體操, 第8節." << endl; 
} 


//第9套廣播體操 
class BroadcastGymNinth : public TemplateMethod 
{ 
public: 
	BroadcastGymNinth(); 
	~BroadcastGymNinth(); 
protected: 
	void Section1st(); 
    void Section2nd(); 
    void Section3rd(); 
    void Section4th(); 
    void Section5th(); 
    void Section6th(); 
    void Section7th(); 
    void Section8th();
}; 

//第套廣播體操 
BroadcastGymNinth::BroadcastGymNinth() 
{} 
BroadcastGymNinth::~BroadcastGymNinth() 
{} 
void BroadcastGymNinth::Section1st() 
{ 
    cout << "第九套廣播體操, 第1節." << endl; 
} 
void BroadcastGymNinth::Section2nd() 
{ 
    cout << "第九套廣播體操, 第2節." << endl; 
} 
void BroadcastGymNinth::Section3rd() 
{ 
    cout << "第九套廣播體操, 第3節." << endl; 
} 
void BroadcastGymNinth::Section4th() 
{ 
    cout << "第九套廣播體操, 第4節." << endl; 
} 
void BroadcastGymNinth::Section5th() 
{ 
    cout << "第九套廣播體操, 第5節." << endl; 
} 
void BroadcastGymNinth::Section6th() 
{ 
    cout << "第九套廣播體操, 第6節." << endl; 
} 
void BroadcastGymNinth::Section7th() 
{ 
    cout << "第九套廣播體操, 第7節." << endl; 
} 
void BroadcastGymNinth::Section8th() 
{ 
    cout << "第九套廣播體操, 第8節." << endl;
} 

上述程式碼類圖表示如下:


呼叫者程式碼:

/* 模板方法模式 */
//第八套廣播體操 
TemplateMethod* t = new BroadcastGymEighth(); 
t->DoGym();
delete t; 
t = NULL;
//第九套廣播體操 
t = new BroadcastGymNinth(); 
t->DoGym();
delete t; 
t = NULL; 

3. Template Method模式附加說明:

當不變的和可變的行為在方法的子類實現中混合在一起的時候,不變的行為就會在子類中重複出現。

我們通過模板方法模式,把這些行為搬移到單一的地方,這樣就可以幫助子類擺脫重複的不變行為的糾纏。

三、Strategy模式和Template Method模式的比較:

1. Strategy模式

  • 定義一系列的演算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得演算法的變化可獨立於使用它的客戶。
  • 使用委託來改變整個演算法。

2. Template Method模式

  • 定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。
  • 使用繼承來改變演算法的一部分。

相關推薦

Strategy模式Template Method模式異同淺析

一、Strategy模式 1. 特點說明: 定義一系列的演算法,把它們一個個封裝起來,並且使它們可相互替換。適用場景: 許多相關的類僅僅是行為有異。“策略”提供了一種用多個行為中的一個行為來配置一個類的方法。需要使用一個演算法的不同變體。演算法使用客戶不應該知道的資料。使用

設計模式Template Method模式

       Template Method模式,模板方法模式。顧名思義,其定義就是在父類中定義處理流程的框架,在子類中實現具體的處理方式。先直接上程式碼,然後我們再來討論這種模式。現在的大概需求是這樣的。 傳入一個char型'A',列印如下結果: 輸入“Hello Wo

設計模式Template Method模式

Template Method模式——將具體處理交給子類 Template Method 模式是帶有模板功能的模式,組成模板的方法被定義在父類中。由於這些方法是抽象方法,所以只檢視父類的程式碼是無法知道這些方法最終會進行何種具體處理的,唯一能知道的就是父類是如

Template Method模式Strategy模式有何異同

Template Method模式很容易理解,就是由基類提供一個模板,將各子類中不變的行為提取到基類中實現,而各子類中可變的行為則由各子類自己重寫基類方法實現.  Strategy則是在使用策略模式的應用例項內部維護一個策略例項,針對不同的子類用不同的策略實現.  來看看兩者的程式碼實現:  Templat

Template Method模式Strategy模式:繼承與委託

Themeplate Method public abstract class Application { protected abstract void init(); protected abstract void idle(); protected abstra

Template Method模式Strategy模式的理解

/** * Strategu模式,把公用方法抽象成介面 * @author paul * @date 2006-8-9 */publicabstractclass Beverage {    /**     * 業務邏輯的實現,final確保不被子類 改變     * prepareRecipe void  

設計模式系列之四_策略模式 模版方法模式(Template method)

1.策略模式 1.1 策略模式   策略模式定義了一系列的演算法,並將每一個演算法封裝起來,而且使它們還可以相互替換。 策略模式讓演算法獨立於使用它的客戶而獨立變化。   策略模式屬於物件的行為模式。其用意是針對一組演算法,將每一個演算法封裝到具有 共同介面的獨立的類中,

封裝算法: 模板方法(Template Method)模式

code cti tracking ref fun hid edi ber 重定義 template method(模板方法)模式是一種行為型設計模式。它在一個方法中定義了算法的骨架(這種方法被稱為template method。模板方法),並將算法的詳

設計模式(22)--Template Method(模板方法模式)--行為型

fur cli 由於 temp img style spa ted prop 1.模式定義:   模板方法模式是類的行為模式。準備一個抽象類,將部分邏輯以具體方法以及具體構造函數的形式實現,然後聲明一些抽象方法來迫使子類實現剩余的邏輯。不同的子類可以以不同的方式實現這些

模板方法模式Template Method

student 客戶 args 提高 prepare sid 行為 right 調用 定義: 定義一個模板結構,將具體內容延遲到子類去實現。 解決的問題: 提高代碼復用性。將相同部分的代碼放在抽象的父類中,而將不同的代碼放入不同的子類中 實現了反向控制。通

GoF之模板方法模式Template Method

釋放 wid 情況 gpo 在線遊戲 一點 需要 eth inf 定義:   在一個操作方法中定義算法的流程,其中這些步驟由子類完成。模板方法模式讓子類 在不變更原有算法流程的情況下,能夠重新定義其中的步驟。   上述的定義中包含兩個方面:     定義一個算法的流程,即是

GOF23設計模式之模板方法模式template method

評分 end 抽象方法 abs 方法調用 轉移 pri spa 應用 一、模板方法模式概述   模板方法模式是編程中經常使用的模式。它定義了一種操作中的算法架構,將某些步驟延遲到子類中實現。這樣,新的子類可以在不改變一個算法結構的前提下重新定義該算法的某些特定步驟。   (

C#設計模式之十三模板方法模式Template Method Pattern)【行為型】

並集 client 變化 args 集中 pac 爸爸 rim 自己 原文:C#設計模式之十三模板方法模式(Template Method Pattern)【行為型】一、引言 “結構型”的設計模式已經寫完了,從今天我們開始講“行為型”設計模式。現在我們開始講【行為型】設

c#設計模式系列:模板方法模式Template Method Pattern)

出了 strong view crete question ron 屬於 png 過多 引言 提到模板,大家肯定不免想到生活中的“簡歷模板”、“論文模板”、“Word中模版文件”等,在現實生活中,模板的概念就是——有一個規定的格式,然後每個人都可以根據自己的需求或情況去更

[設計模式] - No.6 Template Method 模式

Template Method顧名思義,就是說父類在其內部定義了一些抽象函式,然後定義了一個模板方法,並在模板方法中呼叫了這些抽象方法。父類在模板方法中定義了某個功能處理流程的框架,而子類則實現具體的處理。這個例子非常簡單,其核心的理念就是使邏輯處理通用化。 我們通過書中的一個簡單的

設計模式3.Template Method(模板方法)

設計模式目的: 模板方法,在父類中定義好演算法步驟順序,將演算法中的某一具體部分延遲到子類中實現,使得可以在不改變演算法的前提下,將體重特定的部分改變實現。 XML類圖: 模式核心概述: 從模式描述中就能知道,模板方法模式的類圖很簡單,僅涉及到父類

Java設計模式之一——模板方法設計模式Template Method

設計原則:不要重複 DRY(Don’t Repeat Yourself,不要複製自己) OAOO(Once and Only once,僅此一次):避免程式碼重複 GOF給出的模板方法模式定義如下: Define the skeleton of an algorith

Java23種設計模式【19】----》模板方法模式template method

一、場景 流程骨架清楚,但具體實現還不清楚 如吃飯,吃飯流程都知道,但具體吃什麼飯不清楚 二、模板方法模式介紹 定義好骨架,但具體某個方法該怎麼調不知道 三、核心 四、方法回撥(鉤子方法) 五、什麼時候用模板方法模式 六、開發中的場景 七

Java設計模式之從[歡迎介面]分析模板方法(Template Method)模式

  模板方法是在抽象類中最常用的模式了(應該沒有之一),它定義一個操作中演算法的骨架,而將一些步驟延遲到子類中,使得子類可以不改變一個演算法的結構即可重新定義演算法的某些步驟。   例如我們要編寫一個歡迎介面,如果使用者是第一次開啟本軟體,則彈出一個歡迎的提示。為了能夠實現

模板方法模式template Method

這種設計模式在Junit中被使用,如setUp方法與tearDown方法,在JUnit中規定了先執行setUp後執行tearDown但是沒有規定具體執行內容 //在抽象類中可以規定模板方法的執行順序,在介面中不能 public abstract class Abstract