1 概念
策略模式:它定義了算法家族拣技,分別封裝起來,讓它們之間可以相互替換静袖,此模式讓算法的變化寡痰,不會影響到使用算法的客戶抗楔。
2 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圖
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ī)則,就可以考慮使用策略模式處理這種變化的可能性嘱腥。