《大話設(shè)計模式》復(fù)習(xí)總結(jié) -- 策略模式

1 概念

策略模式:它定義了算法家族拣技,分別封裝起來,讓它們之間可以相互替換静袖,此模式讓算法的變化寡痰,不會影響到使用算法的客戶抗楔。

2 UML圖


圖1 策略模式的UML圖

3 C++示例代碼

strategy.h

#include <iostream>

class Strategy {
public:
? ? virtual void AlgorithmInterface() = 0;
};

class StrategyA: public Strategy {
public:
? ? void AlgorithmInterface() override;
};

class StrategyB: public Strategy {
public:
? ? void AlgorithmInterface() override;
};

class StrategyC: public Strategy {
public:
? ? void AlgorithmInterface() override;
};

class Context {
public:
? ? Context(Strategy* strategy);
? ? void ContextInterface();

private:
? ? Strategy* m_strategyPtr = nullptr; ? // 這里體現(xiàn)了Context與Strategy之間的聚合關(guān)系
};

strategy.cpp

#include <iostream>
#include <string>
#include "strategy.h"

using namespace std;

void StrategyA::AlgorithmInterface()
{
? ? cout << "StrategyA Algorithm" << endl;
}

void StrategyB::AlgorithmInterface()
{
? ? cout << "StrategyB Algorithm" << endl;
}

void StrategyC::AlgorithmInterface()
{
? ? cout << "StrategyC Algorithm" << endl;
}

Context::Context(Strategy* strategy)
{
? ? m_strategyPtr = strategy;
}

void Context::ContextInterface()
{
? ? if (m_strategyPtr == nullptr) {
? ? ? ? cout << "Type is invalid" << endl;?
? ? ? ? return;
? ? }

? ? m_strategyPtr->AlgorithmInterface();
}

int main(int argc, char *argv[])
{
? ? Strategy *strategy = nullptr;

? ? if (argc < 2) {
? ? ? ? cout << "Input param error" << endl;
? ? ? ? return -1;
? ? }

? ? // 可以看到棋凳,此時客戶端不僅需要認(rèn)識Strategy類, 還得知道StrategyA等Strategy子類的存在
? ? // 并且连躏,客戶端里面根據(jù)不同的條件分支new出不同的對象
? ? int type = stoi(argv[1]);
? ? switch (type) {
? ? ? ? case 0:
? ? ? ? ? ? strategy = new StrategyA;
? ? ? ? ? ? break;
? ? ? ? case 1:
? ? ? ? ? ? strategy = new StrategyB;
? ? ? ? ? ? break;
? ? ? ? case 2:
? ? ? ? ? ? strategy = new StrategyC;
? ? ? ? ? ? break;
? ? ? ? default:
? ? ? ? ? ? break;
? ? }

? ? if (strategy == nullptr) {
? ? ? ? cout << "Type is invalid" << endl;
? ? ? ? return -1;
? ? }

? ? Context context(strategy);
? ? context.ContextInterface();
? ? return 0;
}

4 總結(jié)

可以看到剩岳,簡單策略模式里面,客戶端的代碼是需要知道StrategyA入热、StrategyB拍棕、StrategyC的存在的,并且勺良,在實際使用過程中绰播,需要在客戶端里面用if else或者switch case等分支語句來控制new出StrategyA、StrategyB尚困、StrategyC幅垮,然后傳入Context,再調(diào)Context的ContextInterface接口尾组。

這種在客戶端里面根據(jù)不同的條件分支new出不同的對象,正是前面講到的工廠模式解決的問題示弓,因此讳侨,很自然的就想到把工廠模式和策略模式結(jié)合,進(jìn)一步優(yōu)化代碼奏属。

策略模式與工廠模式結(jié)合的UML圖


圖2 策略模式與簡單工廠模式結(jié)合的UML圖

C++示例代碼

strategy.h

#include <iostream>

class Strategy {
public:
? ? virtual void AlgorithmInterface() = 0;
};

class StrategyA: public Strategy {
public:
? ? void AlgorithmInterface() override;
};

class StrategyB: public Strategy {
public:
? ? void AlgorithmInterface() override;
};

class StrategyC: public Strategy {
public:
? ? void AlgorithmInterface() override;
};

class Context {
public:
? ? Context(int type);
? ? void ContextInterface();

private:
? ? Strategy* m_strategyPtr = nullptr; ? // 這里體現(xiàn)了Context與Strategy之間的聚合關(guān)系
};

strategy.cpp

#include <iostream>
#include <string>
#include "strategy.h"

using namespace std;

void StrategyA::AlgorithmInterface()
{
? ? cout << "StrategyA Algorithm" << endl;
}

void StrategyB::AlgorithmInterface()
{
? ? cout << "StrategyB Algorithm" << endl;
}

void StrategyC::AlgorithmInterface()
{
? ? cout << "StrategyC Algorithm" << endl;
}

Context::Context(int type)
{
? ? switch (type) {
? ? ? ? case 0:
? ? ? ? ? ? m_strategyPtr = new StrategyA;
? ? ? ? ? ? break;
? ? ? ? case 1:
? ? ? ? ? ? m_strategyPtr = new StrategyB;
? ? ? ? ? ? break;
? ? ? ? case 2:
? ? ? ? ? ? m_strategyPtr = new StrategyC;
? ? ? ? ? ? break;
? ? ? ? default:
? ? ? ? ? ? break;
? ? }
}

void Context::ContextInterface()
{
? ? if (m_strategyPtr == nullptr) {
? ? ? ? cout << "Type is invalid" << endl;
? ? ? ? return;
? ? }

? ? m_strategyPtr->AlgorithmInterface();
}

int main(int argc, char *argv[])
{
? ? if (argc < 2) {
? ? ? ? cout << "Input param error" << endl;
? ? ? ? return -1;
? ? }

? ? // 可以看到跨跨,此時客戶端只需要認(rèn)識Context一個類就夠了
? ? int type = stoi(argv[1]);
? ? Context context(type);
? ? context.ContextInterface();
? ? return 0;
}

策略模式就是用來封裝算法的,但在實踐中囱皿,我們發(fā)現(xiàn)可以用它來封裝幾乎任何類型的規(guī)則勇婴,只要在分析過程中聽到需要在不同時間應(yīng)用不同的業(yè)務(wù)規(guī)則,就可以考慮使用策略模式處理這種變化的可能性嘱腥。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末耕渴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子齿兔,更是在濱河造成了極大的恐慌橱脸,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件分苇,死亡現(xiàn)場離奇詭異添诉,居然都是意外死亡,警方通過查閱死者的電腦和手機医寿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門栏赴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人靖秩,你說我怎么就攤上這事须眷∈” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵柒爸,是天一觀的道長准浴。 經(jīng)常有香客問我,道長捎稚,這世上最難降的妖魔是什么乐横? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮今野,結(jié)果婚禮上葡公,老公的妹妹穿的比我還像新娘。我一直安慰自己条霜,他們只是感情好催什,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宰睡,像睡著了一般蒲凶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拆内,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天旋圆,我揣著相機與錄音,去河邊找鬼麸恍。 笑死灵巧,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抹沪。 我是一名探鬼主播刻肄,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼融欧!你這毒婦竟也來了敏弃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蹬癌,失蹤者是張志新(化名)和其女友劉穎权她,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逝薪,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡隅要,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了董济。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片步清。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出廓啊,到底是詐尸還是另有隱情欢搜,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布谴轮,位于F島的核電站炒瘟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏第步。R本人自食惡果不足惜疮装,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望粘都。 院中可真熱鬧廓推,春花似錦、人聲如沸翩隧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽堆生。三九已至专缠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淑仆,已是汗流浹背藤肢。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留糯景,地道東北人。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓省骂,卻偏偏與公主長得像蟀淮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子钞澳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容