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; }