1. 程式人生 > 其它 >C++ 常用設計模式學習——策略模式

C++ 常用設計模式學習——策略模式

策略模式是指定義一系列的演算法,把它們單獨封裝起來,並且使它們可以互相替換,使得演算法可以獨立於使用它的客戶端而變化,也是說這些演算法所完成的功能型別是一樣的,對外介面也是一樣的,只是不同的策略為引起環境角色(持有一個策略類的引用,最終給客戶端呼叫)表現出不同的行為。

相比於使用大量的if...else,使用策略模式可以降低複雜度,使得程式碼更容易維護。

缺點:可能需要定義大量的策略類,並且這些策略類都要提供給客戶端。

當存在以下情況時使用策略模式:

(1)許多相關的類僅僅是行為有異。“策略”提供了一種用多個行為中的一個行為來配置一個類的方法;

(2)需要使用一個演算法的不同變體;

(3)演算法使用客戶不應該知道的資料。可使用策略模式以避免暴露覆雜的、與演算法相關的資料結構;

(4)一個類定義了多種行為,並且這些行為在這個類的操作中以多個條件語句的形式出現,將相關的條件分支移入它們各自的Strategy類中以替代這些條件語句。

Strategy:定義所有支援的演算法的公共介面。Context使用這個介面來呼叫某ConcreteStrategy定義的演算法;
ConcreteStrategy:實現Strategy介面的具體演算法;
Context:使用一個ConcreteStrategy物件來配置;維護一個對Stategy物件的引用,同時,可以定義一個介面來讓Stategy訪問它的資料。

傳統的策略模式實現

/*
* 關鍵程式碼:實現同一個介面。
* 以下程式碼例項中,以遊戲角色不同的攻擊方式為不同的策略,遊戲角色即為執行不同策略的環境角色。
*/ ​ #include <iostream>using namespace std; ​ //抽象策略類,提供一個介面 class Hurt { public: virtual void blood() = 0; }; ​ //具體的策略實現類,具體實現介面, Adc持續普通攻擊 class AdcHurt : public Hurt { public: void blood() override { cout << "Adc hurt, Blood loss" << endl; } }; ​ //具體的策略實現類,具體實現介面, Apc技能攻擊
class ApcHurt : public Hurt { public: void blood() override { cout << "Apc Hurt, Blood loss" << endl; } }; ​ //環境角色類, 遊戲角色戰士,傳入一個策略類指標引數。 class Soldier { public: Soldier(Hurt* hurt):m_pHurt(hurt) { } //在不同的策略下,該遊戲角色表現出不同的攻擊 void attack() { m_pHurt->blood(); } private: Hurt* m_pHurt; }; ​ //定義策略標籤 typedef enum { Hurt_Type_Adc, Hurt_Type_Apc, Hurt_Type_Num }HurtType; ​ //環境角色類, 遊戲角色法師,傳入一個策略標籤引數。 class Mage { public: Mage(HurtType type) { switch(type) { case Hurt_Type_Adc: m_pHurt = new AdcHurt(); break; case Hurt_Type_Apc: m_pHurt = new ApcHurt(); break; default: break; } } ~Mage() { delete m_pHurt; m_pHurt = nullptr; cout << "~Mage()" << endl; } ​ void attack() { m_pHurt->blood(); } private: Hurt* m_pHurt; }; ​ //環境角色類, 遊戲角色弓箭手,實現模板傳遞策略。 template<typename T> class Archer { public: void attack() { m_hurt.blood(); } private: T m_hurt; }; ​ int main() { Archer<ApcHurt>* arc = new Archer<ApcHurt>; arc->attack(); ​ delete arc; arc = nullptr; return 0; }

使用函式指標實現策略模式

#include <iostream>
#include <functional>void adcHurt()
{
    std::cout << "Adc Hurt" << std::endl;
}
​
void apcHurt()
{
    std::cout << "Apc Hurt" << std::endl;
}
​
//環境角色類, 使用傳統的函式指標
class Soldier
{
public:
    typedef void (*Function)();
    Soldier(Function fun): m_fun(fun)
    {
    }
    void attack()
    {
        m_fun();
    }
private:
    Function m_fun;
};
​
//環境角色類, 使用std::function<>
class Mage
{
public:
    typedef std::function<void()> Function;
​
    Mage(Function fun): m_fun(fun)
    {
    }
    void attack()
    {
        m_fun();
    }
private:
    Function m_fun;
};
​
int main()
{
    Soldier* soldier = new Soldier(apcHurt);
    soldier->attack();
    delete soldier;
    soldier = nullptr;
    return 0;
}

本文來自部落格園,作者:Jcpeng_std,轉載請註明原文連結:https://www.cnblogs.com/JCpeng/p/15110419.html