策略模式
- 定义
- 定义一系列的算法,把他们封装起来,并且使它们可以相互替换。该模式使得算法可独立于使用它们的客户而变化。
- 实现描述
- 使用的客户类中包含算法的抽象类,算法的具体实现类则继承抽象类并且具体实现算法接口,将算法的抽象类作为使用的客户类的构造参数,在客户类构造时传入。客户类在之后使用不同算法可以直接调用不同的算法类。
UML 类图
时序图
使用场景
- 存在以下场景使用策略模式
- 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法
- 需要使用一个算法的不同变种
- 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构
- 一个类定义了多种行为,并且这种行为在这个类的操作中以多个语句的形式出现。
优缺点
代码实现
// 摘自大话设计模式
#include<iostream>
using namespace std;
// 抽象收费策略
class CashSuper
{
private:
/* data */
public:
virtual double acceptCash(double) = 0;
};
// 正常收费类
class CashNornal: public CashSuper{
public:
virtual double acceptCash(double money){
return money;
}
};
// 打折收费类
class CashRebate : public CashSuper {
public:
CashRebate(double money_rebate) {
mMoneyRebate = money_rebate;
}
virtual double acceptCash(double money) {
return money * mMoneyRebate;
}
private:
double mMoneyRebate = 1.0;
};
// 返利收费类
class CashReturn : public CashSuper {
public:
CashReturn(double money_condition, double money_return) {
mMoneyCondition = money_condition;
mMoneyReturn = money_return;
}
virtual double acceptCash(double money){
double result = money;
if(money >= mMoneyCondition) {
result = money - (int)(money / mMoneyCondition) * mMoneyReturn;
return result;
}
return result;
}
private:
double mMoneyCondition = 0;
double mMoneyReturn = 0;
};
class CashContext{
public:
CashContext(CashSuper* pCashSuper){
mPCashSuper = pCashSuper;
}
double ContextInterface(double money){
return mPCashSuper->acceptCash(money);
}
~CashContext(){
if(this->mPCashSuper != nullptr){
delete mPCashSuper;
}
}
public:
CashSuper* mPCashSuper = nullptr;
};
int main()
{
CashContext* context = NULL;
context = new CashContext(new CashNornal());
cout << "cahsNormal : " << context->ContextInterface(700) << endl;
context = new CashContext(new CashRebate(0.8));
cout << "CashRebate : " << context->ContextInterface(700) << endl;
context = new CashContext(new CashReturn(300,100));
cout << "CashRebate : " << context->ContextInterface(700) << endl;
return 0;
}
// 摘自网络(https://www.cnblogs.com/ring1992/p/9593575.html)
typedef enum StrategyType{
StrategyA,
StrategyB,
StrategyC
}STRATEGYTYPE;
class Strategy
{
public:
virtual void AlgorithmInterface() = 0;
virtual ~Strategy() = 0;
};
Strategy::~Strategy(){}
class ConcreteStrategyA : public Strategy
{
public:
void AlgorithmInterface(){
cout << "I am from ConcreteStrategyA." << endl;
}
~ConcreteStrategyA(){}
};
class ConcreteStrategyB : public Strategy
{
public:
void AlgorithmInterface(){
cout << "I am from ConcreteStrategyB." << endl;
}
~ConcreteStrategyB(){}
};
class ConcreteStrategyC : public Strategy
{
public:
void AlgorithmInterface(){
cout << "I am from ConcreteStrategyC." << endl;
}
~ConcreteStrategyC(){}
};
class Context
{
public:
Context(STRATEGYTYPE enum_strategy_type){
switch (enum_strategy_type)
{
case StrategyA:
pStrategy = new ConcreteStrategyA;
break;
case StrategyB:
pStrategy = new ConcreteStrategyB;
break;
case StrategyC:
pStrategy = new ConcreteStrategyC;
break;
default:
break;
}
}
~Context(){
if(pStrategy){
delete pStrategy;
pStrategy = NULL;
}
}
void callAlgorithm(){
if(pStrategy){
pStrategy->AlgorithmInterface();
}
}
private:
Strategy* pStrategy;
};
int main()
{
Context *pContext = new Context(StrategyA);
pContext->callAlgorithm();
return 0;
}
总结