1. 程式人生 > 實用技巧 >c++ 設計模式概述之策略

c++ 設計模式概述之策略

程式碼寫的不規範,目的是為了縮短文章篇幅,實際中請不要這樣做。

1、概述

  類比現實生活中的場景,比如,我需要一塊8G記憶體條,我可以選擇:A、去線下實體店買,B、線上購買,C、其他渠道。 再比如,吃飯餐具選擇,A、用筷子,B、用勺子。 再來一個例子, 外出旅行交通方式: A、坐飛機,B、坐火車,C、坐船、D、騎自行車。 解決問題可能存在多種解決方案。然而每一種對應的方案都可以解決對應問題,可根據實際情況選擇。

  想起來沒 ? 這個背景和工廠模式中的某個方法很相似? 再想想。 對,就是簡單工廠中的工廠生產物件的方法,當加入一個新的物件, 就需要做 if_else 或者 switch_case或者map查詢判斷這樣的情況。物件不同多了,對應的分支就多,不易維護。

  策略模式的主要角色如下:
    A、抽象策略(Strategy)類:定義了一個公共介面,各種不同的演算法以不同的方式實現這個介面,環境角色使用這個介面呼叫不同的演算法,一般使用介面或抽象類實現。
    B、具體策略(Concrete Strategy)類:實現了抽象策略定義的介面,提供具體的演算法實現。
    C、環境(Context)類:持有一個策略類的引用,最終給客戶端呼叫。

  最近一直在弄加密演算法,演算法有多種: aes, rsa, md5. hash, 加密型別: 字串加密的,檔案加密的。 下面以 字串加密為例。

  

2、抽象類,提供標準介面

// 定義加密字串演算法介面
class
encrypt { public: virtual void encrypt_str() = 0; };

3、AES加密類。繼承上面的抽象類,

// 採用AES加密字串
class encrypt_aes : public encrypt
{
public:
    void encrypt_str() { std::cout << "\n採用【AES】加密演算法加密字串\n"; }
};

4、RSA加密類, 繼承上面的抽象類,

// RSA演算法加密字串
class encrypt_rsa : public encrypt
{
public:
    void encrypt_str() { std::cout << "
\n採用【RSA】加密演算法加密字串\n"; } };

5、加密上下文,

// 加密環境
class encrypt_context
{
public:

    // 採用何種加密演算法
    void set_encrypt_type(encrypt *pinstance)
    {
        if (nullptr != pinstance)
            _pencrypt = pinstance;
    }

    // 獲取是何種加密演算法
    encrypt* get_encrypt_type() { return _pencrypt; }

private:
    encrypt *_pencrypt = nullptr;
};

6、執行加密,範例

void call_strategy()
{
    std::unique_ptr<encrypt> paes(new encrypt_aes);
    std::unique_ptr<encrypt> prsa(new encrypt_rsa);
    std::unique_ptr<encrypt_context> pcontext(new encrypt_context);

    if (!paes || !prsa || !pcontext)
    {
        std::cout << "\n加密演算法或者加密環境還沒有準備好\n";
        return;
    }

    std::cout << "\n\n 下面開始加密演示\n1、aes加密:";
    encrypt *pret_val = nullptr;
    
    pcontext->set_encrypt_type(paes.get());
    pret_val = pcontext->get_encrypt_type();
    if (nullptr != pret_val)
        pret_val->encrypt_str();



    std::cout << "\n\n2、下面開始演示rsa加密,";
    pret_val = nullptr;
    pcontext->set_encrypt_type(prsa.get());
    pret_val = pcontext->get_encrypt_type();

    if (nullptr != pret_val)
        pret_val->encrypt_str();
}

7、加密結果