设计模式 -- 策略模式Strategy

来源:互联网 发布:appstore日本福利软件 编辑:程序博客网 时间:2024/05/22 10:48

策略模式:定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。


组成:

  • 抽象策略角色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;}