1、定义
定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。该模式使得算法可独立于使用它的客户程序而变化。 ——《设计模式》 GoF
2、代码实现
代码背景:某商场每个节假日有固定促销活动,现在国庆到了,为了加大促销力度,现提升国庆节促销活动规格
(节日是变化的,每年到一个节日就需要调整今年的促销策略,所以每个节日的促销策略是经常要变的)
class Context { //上下文:在开发中根据上下文作出不同的策略调整
//...
};
//促销策略父类
class ProStategy {
public:
virtual double CalcPro(const Context &ctx) = 0;
virtual ~ProStategy();
};
//以下各种节日继承父类,并根据自己的需求重写促销策略(当需要更改节日促销策略的时候,不需要该其他的代码,维护方便)
class VAC_Spring : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
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){}
};
class VAC_Wuyi : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
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_GuoQing();
Promotion *p = new Promotion(s);
//根据上下文计算促销力度
p->CalcPromotion(ctx);
return 0;
}
代码分析:
-
先定义一个促销策略抽象父类,让每个节日策略继承,并重写自己的促销策略
(当以后需要变更某个节日促销策略的时候,就该对应类的代码就行了,其他地方的代码不用改,这样便于维护)
-
定义促销类,用于切换各个节日促销策略算法,它仅仅是用于调度这些算法
-
使用:定义促销类和促销策略对象传入,促销类调用该对象的促销策略
3、要点
-
策略模式提供了一系列可重用的算法,从而可以使得类型在运⾏时方便地根据需要在各个算法之间进行切换
-
策略模式消除了条件判断语句,也就是在解耦合
-
总结:策略模式可以根据当前的需要在各个算法间切换,同时也降低了耦合度,也便于后期代码维护和扩展
4、本质
- 分离算法—解耦合,每个算法相互独立便于维护
- 选择性执行—在各个算法间切换