定义
定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。该模式使得算法可独立于使用
它的客户程序而变化。 ——《设计模式》 GoF
背景
某商场节假日有固定促销活动,为了加大促销力度,现提升国庆节促销活动规格;
代码strategy1
在这里插入代码片enum VacationEnum { VAC_Spring, VAC_QiXi, VAC_Wuyi, VAC_GuoQing, //VAC_ShengDan, }; // 稳定的 变化的 class Promotion { VacationEnum vac; public: double CalcPromotion(){ if (vac == VAC_Spring){ // 春节 } else if (vac == VAC_QiXi){ // 七夕 } else if (vac == VAC_Wuyi){ // 五一 } else if (vac == VAC_GuoQing){ // 国庆 } } };
这种写法有什么问题?计算活动规格应该封装起来,抽象出促销方法;Promotion职责太多了不稳定,把职责抽象,扩展都是单一职责;对Promotion 修改关闭了;要用一个抽象类去关联,使得拓展都是单一职责
代码strategy2
class Context { }; class ProStategy { public: virtual double CalcPro(const Context &ctx) = 0; virtual ~ProStategy(); }; // cpp class VAC_Spring : public ProStategy { public: virtual double CalcPro(const Context &ctx){} }; // cpp class VAC_QiXi : public ProStategy { public: virtual double CalcPro(const Context &ctx){} }; class VAC_QiXi1 : public VAC_QiXi { public: virtual double CalcPro(const Context &ctx){} }; // cpp class VAC_Wuyi : public ProStategy { public: virtual double CalcPro(const Context &ctx){} }; // cpp class VAC_GuoQing : public ProStategy { public: virtual double CalcPro(const Context &ctx){} }; class VAC_Shengdan : public ProStategy { public: virtual double CalcPro(const Context &ctx){} }; // 稳定的 变化的 class Promotion { public: Promotion(ProStategy *sss) : s(sss){} ~Promotion(){} double CalcPromotion(const Context &ctx){ return s->CalcPro(ctx); } private: ProStategy *s; }; int main () { Context ctx; ProStategy *s = new VAC_QiXi1(); Promotion *p = new Promotion(s); p->CalcPromotion(ctx); return 0; }
要点
- 策略模式提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换;
- 策略模式消除了条件判断语句;就是在解耦合;
- 充分体现了开闭原则;单一职责;
本质
- 分离算法,选择实现;
结构图