您的位置:首页 > 其它

设计模式之二 商场促销-策略模式

2010-10-24 20:11 381 查看
策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。

策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。

代码写完之后,感觉它与简单工厂模式区别不是很大,就是让用户只需要认识context一个类就行了,简单工厂的话多认识一个cashsuper类。

下面分别列举简单工厂,策略模式,策略模式结合简单工厂实现的代码(不知道如何上传整个源码)

简单工厂模式

CashSuperMarket类 CashNormal类 CashRebate类 CashReturn类继承于CashSuperMarket类
class CashSuperMarket
{
	//抽象方法:收取现金,参数为原价,返回为当前价
public:
	virtual double acceptCash(double money)
	{
		return 0.0;
	};
	int GetPoint(double money, double moneyCondition, int pointReturn)
	{
		int point;
		int x = (money / moneyCondition);
		if(money >= moneyCondition)
			point = x*pointReturn;
		return point;
	}
};
CashNormal类
#include "CashSuperMarket.h"
class CashNormal :public  CashSuperMarket
{
public:
	CashNormal(void)
	{
	}
public:
	~CashNormal(void)
	{
	}
public:
	double acceptCash(double money)
	{
		return money;
	}
};
CashRebate类
#include "CashSuperMarket.h"
//打折收费
class CashRebate : public CashSuperMarket
{
public:
	CashRebate(void)
	{
	}
public:
	~CashRebate(void)
	{
	}
private:
	double moneyRebate;
	//初始化时,必需要输入折扣率,如八折,就是0.8

public://构造函数
	CashRebate(double rebate)
	{
		this->moneyRebate = rebate;
	}

public:
	 double acceptCash(double money)
	{
		return money * moneyRebate;
	}
};
CashReturn类
#include "CashSuperMarket.h"
//返利收费
class CashReturn : public CashSuperMarket
{
public:
	CashReturn(void)
	{
	}
public:
	~CashReturn(void)
	{
	}
private:
	double moneyCondition ;
	double moneyReturn ;
	//初始化时必须要输入返利条件和返利值,比如满300返100,则moneyCondition为300,moneyReturn为100
public:
	CashReturn(double moneyCondition, double moneyReturn)
	{
		this->moneyCondition = moneyCondition;
		this->moneyReturn = moneyReturn;
	}

public:
	double acceptCash(double money)
	{
		double result = money;
		//若大于返利条件,则需要减去返利值
		int x = (money / moneyCondition);
		if (money >= moneyCondition)
			result = money - x * moneyReturn;
		return result;
	}
};

收费对象生成的工厂
#include "CashSuperMarket.h"
#include "CashNormal.h"
#include "CashRebate.h"
#include "CashReturn.h"
//#include "GetPoint.h"

#include <iostream>
using namespace std;
class CashFactory
{
    //根据条件返回相应的对象
public:
	static CashSuperMarket* createCashAccept(int type)
    {
        //CashSuperMarket cs = NULL;
		CashSuperMarket* cs;
		switch(type)
		{
			//case "正常收费":
		case 2:
			{
				cs = new CashNormal();
				break;

			}
		case 1://case "满300返100":
			{
				CashReturn* cr1 = new CashReturn(300, 100);
				cs = cr1;
				break;
				
			}
			
		case 0://case "打8折":
			{
				CashRebate* cr2 = new CashRebate(0.8);
				cs = cr2;
				break;
				
			}
			
		/*case 0:
			{
				GetPoint* cr3 = new GetPoint(100, 10);
				cs = cr3;
				break;
				
			}*/

		}
		return cs;
	}
};

客户端的主要响应函数
void C工厂模式Dlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(true);
	int type = m_pComboBox.GetCurSel();
	CString message;
	m_pComboBox.GetLBText(type, message);
	double money = m_price*m_num;

	CashSuperMarket* cashSuper = CashFactory::createCashAccept(type);
	totalPrice = cashSuper->acceptCash(money);
	total += totalPrice;
	int point = cashSuper->GetPoint(total, 100, 10);
	m_detail.Format("单价:%f 数量:%d折扣:%s本次积分:%d/n合计:%f", m_price, m_num, message , point, total);
	CString  statictotalPrice;
	statictotalPrice.Format("%f", total);
	CStatic*  price = (CStatic*)GetDlgItem(IDC_TOTALPRICE); 
	price->SetWindowText(statictotalPrice);
	UpdateData(false);
}

void C工厂模式Dlg::OnBnClickedReset()
{
	// TODO: 在此添加控件通知处理程序代码
	m_price = 0;
	m_num = 0;
	total = 0;
	m_detail = _T("");
	CStatic*  price = (CStatic*)GetDlgItem(IDC_TOTALPRICE); 
	price->SetWindowText("0");
	UpdateData(false);

}


策略模式

CashNormal类、CashRebate类、 CashReturn类、 CashSuperMarket类保持不变,需要修改的是去掉工厂类,将选择收款方式转移到客户端,新增一个CashContext类

CashContext类
#include "CashSuperMarket.h"

class CashContext
{
public:
	CashContext(void)
	{
	}
public:
	~CashContext(void)
	{
	}
private:
	CashSuperMarket* cs;
public:
	CashContext(CashSuperMarket* csupermarket)
	{
		this->cs = csupermarket;
	}
public:
	double GetResult(double money)
	{
		return cs->acceptCash(money);
	}
};

客户端实现
void C策略模式Dlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(true);
	int type = m_pComboBox.GetCurSel();
	CString message;
	m_pComboBox.GetLBText(type, message);
	double money = m_price*m_num;

	CashContext* cc;
	switch(type)
	{
		//case "正常收费":
	case 2:
		{
			cc = new CashContext(new CashNormal());
			break;
		}
	case 1://case "满300返100":
		{
			 cc = new CashContext(new CashReturn(300, 100));
			break;
		}

	case 0://case "打8折":
		{
			 cc = new CashContext(new CashRebate(0.8));
			break;
		}
	}

	//totalPrice = cashSuper->acceptCash(money);
	totalPrice = cc->GetResult(money);
	total += totalPrice;
	//int point = cashSuper->GetPoint(total, 100, 10);
	/*m_detail.Format("单价:%f 数量:%d折扣:%s本次积分:%d/n合计:%f", m_price, m_num, message , point, total);*/
	m_detail.Format("单价:%f 数量:%d折扣:%s合计:%f", m_price, m_num, message , total);
	CString  statictotalPrice;
	statictotalPrice.Format("%f", total);
	CStatic*  price = (CStatic*)GetDlgItem(IDC_TOTALPRICE); 
	price->SetWindowText(statictotalPrice);
	UpdateData(false);
}


策略模式与工厂模式结合 只需修改CashContext类和客户端的实现部分

CashContext类
#include "CashSuperMarket.h"
#include "CashNormal.h"
#include "CashRebate.h"
#include "CashReturn.h"

class CashContext
{
public:
	CashContext(void)
	{
	}
public:
	~CashContext(void)
	{
	}
private:
	CashSuperMarket* cs;
public:
	CashContext(int type)
	{
		switch(type)
		{
			//case "正常收费":
		case 2:
			{
				cs = new CashNormal();
				break;
			}
		case 1://case "满300返100":
			{
				cs = new CashReturn(300, 100);
				break;
			}

		case 0://case "打8折":
			{
				cs = new CashRebate(0.8);
				break;
			}
		}
	}

	/*CashContext(CashSuperMarket* csupermarket)
	{
		this->cs = csupermarket;
	}*/
public:
	double GetResult(double money)
	{
		return cs->acceptCash(money);
	}
};

客户端实现
void C策略模式&工厂模式Dlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(true);
	int type = m_pComboBox.GetCurSel();
	CString message;
	m_pComboBox.GetLBText(type, message);
	double money = m_price*m_num;

	CashContext* cc = new CashContext(type);
	totalPrice = cc->GetResult(money);
	total += totalPrice;

	m_detail.Format("单价:%f 数量:%d折扣:%s合计:%f", m_price, m_num, message , total);

	CString  statictotalPrice;
	statictotalPrice.Format("%f", total);
	CStatic*  price = (CStatic*)GetDlgItem(IDC_TOTALPRICE); 
	price->SetWindowText(statictotalPrice);
	UpdateData(false);
}




这一章早就该发了,结果因为一些事情拖到今天,呵呵
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: