注:本文主要代码基于大话设计模式里的C#代码(第2章)。
UML图:
策略模式的实现:
将所要用的所有算法抽象出一个接口(所以每个算法要用类实现)
使用一个策略上下文类,封装一个算法接口的指针,并提供一个函数给外部调用具体算法。
外部用具体算法类的指针来创建策略上下文类。
下面代码是一个商场收费系统的抽象,将收费的算法(普通,打折,返利)抽象成cCashSuper接口
在策略上下文类cCashContext中使用工厂模式,可以将具体算法的调用与调用者解耦。
代码如下:
/*****************************************************
* 模式名:策略模式
* 时间:2010.6.3
* -by gouki04
*****************************************************/
#pragma once
//
class cCashContext; // (策略上下文类,封装了一个策略接口的指针)
class cCashContext_Factory; // (策略上下文类与简单工厂模式结合)
class cCashSuper; // 收费类接口(策略接口,定义所有算法的公共接口)
class cCashNormal; // 普通收费类(基本策略类)
class cCashRebate; // 打折收费类(基本策略类)
class cCashReturn; // 返利收费类(基本策略类)
//
// 收费类接口(策略接口,定义所有算法的公共接口)
class cCashSuper
{
public:
// 收费方法
// 参数:money为原收费
// 返回:应收费
virtual double AcceptCash(double money) = 0;
};
// 普通收费类(基本策略类)
class cCashNormal : public cCashSuper
{
public:
double AcceptCash(double money) { return money; }
};
// 打折收费类(基本策略类)
class cCashRebate : public cCashSuper
{
private:
double m_moneyRebate; // 折扣率
public:
cCashRebate(double rebate = 1.0) : m_moneyRebate(rebate) {}
double AcceptCash(double money) { return money * m_moneyRebate; }
};
// 返利收费类(基本策略类)
// 例:满300返100
class cCashReturn : public cCashSuper
{
private:
double m_moneyCondition; // 返还条件的金钱数
double m_moneyReturn; // 返还的金钱数
public:
cCashReturn(double condition = 0.0, double _return = 0.0) : m_moneyCondition(condition), m_moneyReturn(_return) {}
double AcceptCash(double money)
{
if (money > m_moneyCondition)
money -= static_cast<int>(money / m_moneyCondition) * m_moneyReturn;
return money;
}
};
// (策略上下文类,封装了一个策略接口的指针)
class cCashContext
{
private:
cCashSuper * m_pCashSuper;
public:
cCashContext(cCashSuper* cs) : m_pCashSuper(cs) {}
virtual ~cCashContext() { /* 这里没有必要析构m_pCashSuper,因为它是外部引入,应该由外部负责析构 */ }
// 调用具体的收费算法
double AcceptCash(double money) { return m_pCashSuper->AcceptCash(money); }
};
// 策略上下文类与简单工厂模式结合
// 将具体的选择算法的过程封装起来
class cCashContext_Factory
{
private:
cCashSuper * m_pCashSuper;
public:
// 此处的构造函数体应该放在cpp文件中,这里为了方便阅读而改为内联函数
// 像switch这样的语句不应该使用内联
cCashContext_Factory(int type = 0)
{
switch (type) {
case 0:
m_pCashSuper = new cCashNormal();
break;
case 1:
m_pCashSuper = new cCashRebate(0.8);
break;
case 2:
m_pCashSuper = new cCashReturn(300, 100);
break;
default:
throw type;
}
}
virtual ~cCashContext_Factory() { if (m_pCashSuper) delete m_pCashSuper; }
// 调用具体的收费算法
double AcceptCash(double money) { return m_pCashSuper->AcceptCash(money); }
};
// 测试的main函数
//int main()
//{
// using namespace std;
//
// cCashContext* pContext = NULL;
// cCashSuper* pCashSuper = NULL;
// try {
// int type = 0;
// cout << "0 --> 普通收费" << endl << "1 --> 打8折" << endl << "2 --> 满300返100" << endl << "请选择收费方式:";
// cin >> type;
//
// switch (type) {
// case 0:
// pCashSuper = new cCashNormal();
// break;
// case 1:
// pCashSuper = new cCashRebate(0.8);
// break;
// case 2:
// pCashSuper = new cCashReturn(300, 100);
// break;
// default:
// throw type;
// }
// pContext = new cCashContext(pCashSuper);
//
// cout << endl << "总费用为:";
// double totalPrice = 0;
// cin >> totalPrice;
//
// cout << endl << "应收费为:" << pContext->AcceptCash(totalPrice) << endl;
// }
// catch (int type) {
// cout << "没有" << type << "这种收费方式。" << endl;
// }
// catch (...) {
// cout << "输入错误" << endl;
// }
//
// if (pContext)
// delete pContext;
//
// if (pCashSuper)
// delete pCashSuper;
//
// return 0;
//}
// 使用策略模式+工厂模式的main函数
//int main()
//{
// using namespace std;
//
// cCashContext_Factory* pContext = NULL;
//
// try {
// int type = 0;
// cout << "0 --> 普通收费" << endl << "1 --> 打8折" << endl << "2 --> 满300返100" << endl << "请选择收费方式:";
// cin >> type;
// pContext = new cCashContext_Factory(type);
//
// cout << endl << "总费用为:";
// double totalPrice = 0;
// cin >> totalPrice;
//
// cout << endl << "应收费为:" << pContext->AcceptCash(totalPrice) << endl;
// }
// catch (int type) {
// cout << "没有" << type << "这种收费方式。" << endl;
// }
// catch (...) {
// cout << "输入错误" << endl;
// }
//
// if (pContext)
// delete pContext;
//
// return 0;
//}