定義一系列演算法,將每一個封裝起來,並使它們可相互替換。本模式使得演算法可獨立於使用它的客戶而變化。
Strategy 模式就是「對演算法的封裝」。當解決同一問題有多種演算法(介面一致)時,提取共同介面為 Strategy,各演算法實作為 ConcreteStrategy,Context 持有策略指標並委派執行。
#ifndef STRATEGY_H
#define STRATEGY_H
class Strategy;
class Context {
public:
Context(Strategy* pStrategy);
~Context();
void ContextInterface();
private:
Strategy* m_pStrategy;
};
class Strategy {
public:
virtual ~Strategy() {}
virtual void AlgorithmInterface() = 0;
};
class ConcreteStrategyA : public Strategy {
public:
virtual ~ConcreteStrategyA() {}
virtual void AlgorithmInterface();
};
#endif
#include <iostream>
#include "Strategy.h"
Context::Context(Strategy* pStrategy) : m_pStrategy(pStrategy) {}
Context::~Context() { delete m_pStrategy; m_pStrategy = nullptr; }
void Context::ContextInterface() {
if (m_pStrategy) m_pStrategy->AlgorithmInterface();
}
void ConcreteStrategyA::AlgorithmInterface() {
std::cout << "AlgorithmInterface Implemented by ConcreteStrategyA\n";
}
#include "Strategy.h"
int main() {
Strategy* pStrategy = new ConcreteStrategyA();
Context* pContext = new Context(pStrategy);
pContext->ContextInterface();
delete pContext;
return 0;
}
實務上常在 Context 加入 SetStrategy(Strategy*),允許執行期替換:
void Context::SetStrategy(Strategy* pStrategy) {
delete m_pStrategy;
m_pStrategy = pStrategy;
}
// 使用範例
Context ctx(new ConcreteStrategyA());
ctx.ContextInterface(); // 執行 A
ctx.SetStrategy(new ConcreteStrategyB());
ctx.ContextInterface(); // 執行 B
std::function<ReturnType(Args...)> + Lambda:輕量、無需繼承體系。template<typename Strategy> class Context,編譯期綁定,效能最高但無法執行期切換。