zoukankan      html  css  js  c++  java
  • 策略模式

    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;
    }
  • 相关阅读:
    第三次冲刺
    第二次冲刺
    第一次冲刺
    团队学习
    git and github
    还不够格的程序员
    CF1602F. Difficult Mountain
    线性基
    欧拉回路学习笔记
    莫比乌斯反演-学习笔记
  • 原文地址:https://www.cnblogs.com/zxtp/p/4917892.html
Copyright © 2011-2022 走看看