策略模式:定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
组成:
-
抽象策略角色Strategy:策略类,定义了所有支持的算法的公共接口
-
具体策略角色ConcreteStrategyA : Strategy :继承自Strategy,封装了具体的算法或行为,可能有很多。
-
环境角色或者上下文角色,持有一个对Strategy对象的引用,给客户端调用的。
应用场景:eg商场促销;游戏中不同状态下人物的技能
-
多个类只在表现行为不同,在运行时候动态选择不同的行为
-
不同的情况下使用不同的策略(算法),策略很可能在未来用其他方式实现
-
对客户端隐藏算法具体细节,彼此完全独立
优点:
1. 避免代码的重复:把公有的代码放在父类里
2. 继承使得动态改变算法或逻辑变得可能
3. 避免多重条件转移语句
缺点:
客户端必须知道所有的策略类
每个具体策略都对应一个类,这时可以考虑下共享的办法
一个例子:商场打折
结构图如下
#include <iostream>
#include <cmath>
#include <map>
using namespace std;
//抽象算法类 : 现金收费
class CashSuper {
public:
virtual double acceptCash(double money) = 0;
};
//具体算法A:正常收费
class CashNormal : public CashSuper {
public:
double acceptCash(double money)
{
return money;
}
};
//具体算法B:打折收费
class CashRebate : public CashSuper {
public:
CashRebate(double _moneyRebate)
: moneyRebat(_moneyRebate)
{
}
double acceptCash(double money)
{
return money * moneyRebat;
}
private:
double moneyRebat;
};
//具体算法A:返利收费,满?反?
class CashReturn : public CashSuper {
public:
CashReturn(double _moneyCondition = 0.0, double _moneyReturn = 0.0)
: moneyCondition(_moneyCondition), moneyReturn(_moneyReturn)
{
}
double acceptCash(double money)
{
double result = money;
if(money > moneyCondition)
{
result = money - floor(money/moneyCondition) * moneyReturn;
}
return result;
}
private:
double moneyCondition;
double moneyReturn;
};
//上下文Context,与简单工厂模式结合后的产物
class CashContext {
private:
CashSuper *cs = NULL;
public:
CashContext(string type)
{
if(type == "正常收费") {
cs = new CashNormal();
} else if(type == "满300返100") {
cs = new CashReturn(300, 100);
} else if(type == "打8折") {
cs = new CashRebate(0.8);
}
}
double getResult(double money)
{
return cs->acceptCash(money);
}
};
int main() {
double total = 0.0;
CashContext *csuper = new CashContext("正常收费");
total = total + csuper->getResult(5.0 * 4); //单价5.0 * 4个
cout << "单项价格:" << csuper->getResult(5.0 * 4) << endl; //20
delete csuper;
csuper = new CashContext("打8折");
total = total + csuper->getResult(4.0 * 5);
cout << "单项价格:" << csuper->getResult(4.0 * 5) << endl; //16
delete csuper;
csuper = new CashContext("满300返100");
total = total + csuper->getResult(220.0 * 3);
cout << "单项价格:" << csuper->getResult(220.0 * 3) << endl; //460
delete csuper;
cout << "最终的应该付款:" << total << endl; //496
return 0;
}