策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
策略模式就是用来封装算法的,实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性[DPE]。下面将实现一个策略模式是商场的收银系统的demo,参考大话设计模式,利用c++对代码进行了改编。该收银系统有很多计算方式,这里只列举了正常的计算方式、满一定金额返现以及打折这三种方式。这三种算法可以封装成单独的三个类并分别继承一个抽象的算法类,再从一个类里对该三种算法进行处理。贴出代码:
//算法的父类
#ifndef _CASH_H
#define _CASH_H
class Cash
{
public:
virtual ~Cash()
{
}
virtual double PayCash(double __money) = 0;
};
#endif // ! _CASH_H
//正常计算方式
#ifndef _NORMAL_H
#define _NORMAL_H
#include "cash.h"
class PayNormal : public Cash
{
public:
PayNormal() {}
~PayNormal() {}
virtual double PayCash( double __money )
{
return __money;
}
};
#endif
//打折计算方式
#ifndef _REBATE_H
#define _REBATE_H
#include "cash.h"
class PayRebate : public Cash
{
public:
PayRebate(double __rebate)
{
m_rebate = __rebate;
}
~PayRebate() {}
virtual double PayCash(double __money )
{
return (__money*m_rebate);
}
private:
double m_rebate;
};
#endif
//满减计算方式
#ifndef _RETURN_H
#define _RETURN_H
#include "cash.h"
class PayReturn : public Cash
{
public:
PayReturn(double __condition, double __return)
{
m_condition = __condition;
m_return = __return;
}
~PayReturn() {}
virtual double PayCash(double __money)
{
double ret = __money;
if (__money >= m_condition)
{
ret = __money - (__money / m_condition)*m_return;
}
return ret;
}
private:
double m_condition;
double m_return;
};
#endif
//对三种计算方式进行了封装,在主函数里看不到这三个算法类
#ifndef _CONTEXT_H
#define _CONTEXT_H
#include "cash.h"
#include "normal.h"
#include "rebate.h"
#include "returncash.h"
#define NORMAL 1
#define RETURN 2
#define REBATE 3
class Context
{
public:
Context( int __paymethod )
{
m_pCash = NULL;
switch (__paymethod)
{
case NORMAL:
{
m_pCash = new PayNormal();
}
break;
case RETURN:
{
m_pCash = new PayReturn( 300,100);
}
break;
case REBATE:
{
m_pCash = new PayRebate(0.8);
}
break;
default:
break;
}
}
~Context()
{
delete m_pCash;
m_pCash = NULL;
}
double GetReult( double __money )
{
double ret = m_pCash->PayCash(__money);
return ret;
}
private:
Cash *m_pCash;
};
#endif // ! _CONTEXT_H
//run.cpp 主函数里只需要把算法方式给Context类,并把金额给Context类即可
#include <tchar.h>
#include "context.h"
int _tmain(int argc, TCHAR* argv[])
{
Context *text = new Context(NORMAL);
double result = text->GetReult(300);
_tprintf(_T("NORMAL::result == %f\n"), result);
delete text;
text = NULL;
text = new Context(RETURN);
result = text->GetReult(300);
_tprintf(_T("RETURN::result == %f\n"), result);
delete text;
text = NULL;
text = new Context(REBATE);
result = text->GetReult(300);
_tprintf(_T("RETURN::result == %f\n"), result);
delete text;
text = NULL;
}
该程序的UML图如下:
运行结果如下: