1.说明
请参见该系列文章第一章
2.策略模式说明
本质:根据client的需求,调用不同的算法实现,算法经常变更的场所。
通俗:客户为满足不同的场景,预定义了不同的算法,在不同的环境下进行算法切换。达到相同的目的
注意点:由于定义了不同的算法,所以client在使用的时候,会进行判断的方式进行初始化,那么在这个地方其实是可以增添简单工厂模式,将判断的逻辑疲敝起来,client只需要传入条件就可以了
注意点:系统中每次应该只存在一种算法,所以不用提供策略管理,但是在进行算法切换的时候,需要注意清理上一个策略的实例
DP:定义了算法家族,分别封装起来,让他们可以相互替换,不会影响到使用算法的客户
3.UML
4.代码
代码背景:模拟超时收费状况,可能在不同的时间段采用不同优惠政策,有赠送类,
打折类,返利类等,而具体的优惠方式都是通过外部传入的,最后通过简单工厂的方式来判断当前使用的是哪个策略
//算法抽象类
#ifndef __CALGINTERBASE_H
#define __CALGINTERBASE_H
typedef struct SInterPar
{
int type;
void* par;
} TInterPar;
class CAlgInterBase
{
public:
CAlgInterBase(){}
virtual ~CAlgInterBase(){}
virtual double handle(double price, TInterPar* par) = 0;
};
#endif
//赠送类
#ifndef __CALGGIVE_H
#define __CALGGIVE_H
#include "AlgInterBase.h"
//赠送类
typedef struct SGive
{
int givebase;
int giveval;
} TGive;
class CAlgGive:public CAlgInterBase
{
public:
CAlgGive(){}
~CAlgGive(){}
virtual double handle(double price, TInterPar* give)
{
TGive* pgive = (TGive*) give->par;
double pval = price;
if (pval > pgive->givebase)
pval = price - pgive->giveval;
return pval;
}
};
#endif
//返利类
#ifndef __CALGREBATE_H
#define __CALGREBATE_H
#include "AlgInterBase.h"
typedef struct SRebate
{
int retbase; //返利基数
int retval; //返利值
} TRebate;
class CAlgRebate:public CAlgInterBase
{
public:
CAlgRebate(){}
~CAlgRebate(){}
virtual double handle(double price, TInterPar* rebate)
{
TRebate* par = (TRebate*)rebate->par;
int rbase = (int)price/par->retbase;
return (price - rbase*par->retval);
}
};
#endif
//折扣类
#ifndef __CALGRET_H
#define __CALGRET_H
#include "AlgInterBase.h"
//打折类
typedef struct SRet
{
float ret; //折扣率
} TRet;
class CAlgRet:public CAlgInterBase
{
public:
double handle(double price, TInterPar* ret)
{
TRet* pret = (TRet*)ret->par;
return price*pret->ret;
}
};
#endif
//简单工厂方式接口封装类
#ifndef __CCONTEXT_H
#define __CCONTEXT_H
#include <iostream>
#include "AlgInterBase.h"
#include "AlgRebate.h"
#include "AlgRet.h"
#include "AlgGive.h"
enum STRATYPE{ERET, EREBATE, EGIVE};
typedef struct SStrategyPar
{
int type;
void* par;
} TStrategyPar;
class CContext
{
public:
CContext(){
m_AlgBase = NULL;
}
~CContext(){
if (m_AlgBase != NULL)
delete m_AlgBase;
}
CAlgInterBase* concreatestrategy(SStrategyPar* par)
{
if (m_AlgBase != NULL)
{
delete m_AlgBase;
}
switch (par->type)
{
case ERET:
m_AlgBase = new CAlgRet;
break;
case EREBATE:
m_AlgBase = new CAlgRebate;
break;
case EGIVE:
m_AlgBase = new CAlgGive;
break;
default:
m_AlgBase = NULL;
}
return m_AlgBase;
}
double getRes(double price, TInterPar* par)
{
return m_AlgBase->handle(price, par);
}
private:
CAlgInterBase* m_AlgBase;
};
#endif
//客户端调用类
#include <iostream>
#include "Context.h"
//策略模式:感觉和工厂模式有点类似,client只需要知道context OK
//在实现中为了给策略配置参数,选择了void*类型转换
//由于策略的 base为算法,所以每次的时候,系统中只有一种算法,并没有提高策略管理
int main(void)
{
CContext* con = new CContext();
TStrategyPar first;
TStrategyPar second;
TStrategyPar thrd;
TStrategyPar forth;
first.type = ERET;
second.type = EREBATE;
thrd.type = EGIVE;
forth.type = EREBATE;
double price1 = 1024;
double price2 = 1034.5;
double price3 = 9910;
double price4 = 10;
TRebate f1;
TRet f2;
TGive f3;
TRebate f4;
f1.retbase = 200;
f1.retval = 100;
f2.ret = 0.8;
f3.givebase = 5000;
f3.giveval = 1000;
f4.retbase = 100;
f4.retval = 50;
TInterPar tmp;
tmp.par = (void*)&f1;
if (con->concreatestrategy(&first) == NULL)
std::cout<<"first error."<<std::endl;
std::cout<<"first strategy:"<<con->getRes(price1, &tmp)<<std::endl;
tmp.par = (void*)&f2;
if (con->concreatestrategy(&second) == NULL)
std::cout<<"second error."<<std::endl;
std::cout<<"first strategy:"<<con->getRes(price2, &tmp)<<std::endl;
tmp.par = (void*)&f3;
if (con->concreatestrategy(&thrd) == NULL)
std::cout<<"thrd error."<<std::endl;
std::cout<<"first strategy:"<<con->getRes(price3, &tmp)<<std::endl;
tmp.par = (void*)&f4;
if (con->concreatestrategy(&forth) == NULL)
std::cout<<"forth error."<<std::endl;
std::cout<<"first strategy:"<<con->getRes(price4, &tmp)<<std::endl;
return 0;
}