策略模式

1、策略模式:又叫算法簇模式。它定义了一系列的算法,分别封装起来,让他们之间可以相互替换(实现这点,在C++中可以使用指针或者引用),此模式让算法的变化不会影响到使用算法的客户。
2、优点:策略模式的好处在于可以动态改变对象的行为。
3、设计原则:把一个类中经常改变或者将来有可能改变的部分提取出来,作为一个虚类,然后在该虚类的派生类中去实现虚类中的函数。这样在实例中运行时,就可以任意调用实现这个虚类的函数了。策略模式属于对象行为模式,主要针对一组算法,将每一个算法封装到共同虚基类的独立类中,从而是的它们之间可以相互替换。
4、策略模式中有三个对象:
(1)、环境对象:即管理具体对象策略的对象。该对象中主要是对抽象类对象的定义和引用。
(2)、抽象策略对象:它是有抽象类实现的。主要是为算法簇提供统一的接口。
(3)、具体策略对象:它封装了不同功能的不同算法。
5、在实际开发中可以用策略模式封装几乎任何类型的规则,只要在分析过程中指导它需要在不同时间(或不同场景)应用不同的业务规则,就可以考虑用策略模式来处理这种变化的可能性。
6、改进:调用者要对情况进行判断,然后确定创建哪一种策略对象。这就要求调用者必须知道有哪些策略类。当然,在使用策略模式时,还可以对这些判断做进一步封装,留个调用者一个接口,调用者只需要知道这一个接口就可以正常使用了。这就是策略模式与简单工厂模式的结合使用。
 
 
例子:为商城设计一个计算价格的计算器,要求具有打折功能(如打8折)和满减(如满100减20)功能。
1、定义一个公共的接口(抽象策略对象的类)
//定义一个抽象类,为两种功能提供相同的接口,以后可以通过这个接口来调用计价算法
class strategy {
public:
    strategy(float price, int count);
    virtual ~strategy();
    virtual void calculate() = 0;//这里定义一个纯虚函数,在子类去实现它
    void show();//派生类中的显示函数都一样,因此可以在基类中定义并实现,让派生类继承就可以了
protected:
    float price;
    int count;
    float total_price;
};


/*实现show函数*/
void strategy::show()
{
    cout << "惠后总价为:" << this->total_price;
}

2、定义一个打折的类(具体策略对象的类)

//打折类,继承strategy类,以后可以通过strategy类对象来调用它
class discount:public strategy
{
public:
    discount(float price, int count, float rate);
    virtual ~discount();
    virtual void calculate();
private:
    float rate;//折扣,如8折,这里就应该是0.8
};


/*实现该类中的函数*/
discount::discount(float price, int count, float rate):strategy(price, count)//构造函数
{
    this->rate = rate;
}

discount::~discount() {
    // TODO Auto-generated destructor stub
}

void discount::calculate()//计算优惠后的价格
{
    this->total_price = this->price * this->count * this->rate;
}

3、定义一个满减类(具体策略对象的类)

//满减算法类,继承strategy类,使得他们有共同的接口
class full_min:public strategy
{
public:
    full_min(float price, int count, float full, float min);
    virtual ~full_min();
    virtual void calculate();
private:
    float full;//满多少
    float min;//优惠
};

/*实现该类中的函数*/
full_min::full_min(float price, int count, float full, float min):strategy(price, count)
{
    this->full = full;
    this->min = min;
}

full_min::~full_min() {
}

void full_min::calculate()//计算优惠后的价格
{
    this->total_price = this->price * this->count;
    if(this->total_price >= this->full)//如果达到条件,则减价
    {
        int mul = (int)this->total_price / (int)this->full;
        this->total_price -= this->min * mul;
    }
}

4、最后定义一个函数根据实际情况去调用这些算法。(这里相当于上文提到的环境对象,只是这里是用函数实现)

void fun()
{
    int slct;    //优惠方式
    float full;    //满多少
    float min;    //满后减多少
    float price;//单价
    int count;    //购买数量
    float rate;//折扣
    /*定义一个基类指针,用它来指向将要调用的算法类对象。以后的调用都使用它来完成。如果需要添加其它的算法,只要继承strategy类,就可以通过这个指针去调用*/
    strategy *p = NULL;
    while(1)
    {
        cout << "选择优惠方式:1、打折	2、满减:" << endl;
        cin >> slct;
        cout << "请输入单价:" << endl;
        cin >> price;
        cout << "请输入数量:" << endl;
        cin >> count;

        switch(slct)
        {
        case 1://折扣
        {
            cout << "请输入折扣:" << endl;
            cin >> rate;
            p = new discount(price, count, rate);
            break;
        }
        case 2://满减
        {
            cout << "请输入需要满多少:" << endl;
            cin >> full;
            cout << "请输入减多少:" << endl;
            cin >> min;
            p = new full_min(price, count, full, min);
            break;
        }//若以后还需要增加算法,就在这里添加分支就行了,不用去更改其代码
        default:
            cout << "输入有误!" << endl;
            break;
        }
        p->calculate();//根据创建的不同的对象,调用不同的函数
        p->show();//显示最终结果
    }

    delete p;
}

int main(int argc, char *argv[])
{
    fun();
    return 0;
}
原文地址:https://www.cnblogs.com/zxtp/p/4917892.html