设计模式之二: 策略模式

在读大话模式, 对策略模式进行笔记,学习总结;

首先,模拟商场里的收费系统,计算该商品的总的金额,假如搞促销互动,可能是打折;

可能是买多少反现多少

有如下代码:

void   Test_0() 
{
cout << "输入商品的单价: " << endl;
double dPrice;
cin >> dPrice;
cout << "输入商品的数量: " << endl;
int nNumber;
cin >> nNumber;
// cout << "总价: " << nNumber * dPrice << endl;
double dTotal(0.0);
cout << "请输入促销的类型: " << endl;
int nType(0);
cin >> nType;
Promotion_Type eType = (Promotion_Type)nType;
switch (eType) {
case Promotion_Normal:
dTotal = dPrice * nNumber;
break;
case Promotion_0_8:
dTotal = dPrice * nNumber * 0.8;
break;
case Promotion_300_100:
dTotal = dPrice * nNumber - (int)((dPrice * nNumber) / 300) * 100;
break;
}
cout << "需要付款: " << dTotal << endl;
}

那么这么写,所有的业务逻辑都在客户的代码中,在面向对象的思想中,是要将这些逻辑封装起来;

作为功能的提供者,客户只需要调用接口就可以了;

所以针对具体的商场促销,例如正常的情况, 打折的情况, 返现的情况;

// 定义一个用于计算收费的算法
class CashSuper 
{
public:
    virtual  ~CashSuper() {}
    virtual  double GetResult(double dMoney) = 0;
};

// 正常的情况
class  CashNormal : public CashSuper 
{
public:
    virtual  double GetResult(double dMoney) 
    {
        return dMoney;
    }
};

// 打几折
class   RebateCash : public CashSuper 
{
public:
RebateCash(double dRebate)
: m_dRebate(dRebate)
{
}

virtual double GetResult(double dMoney) 
{
return  dMoney * m_dRebate;
}
private:
double   m_dRebate;
};

// 多少返多少现金
class  ReturnCash : public CashSuper 
{
public:
ReturnCash(double cashCondition, double cashReturn) 
: m_cashConditon(cashCondition)
, m_cashReturn(cashReturn)
{
}
virtual  double GetResult(double dMoney) 
{
double dReturnMoney = (int)(dMoney / m_cashConditon) * m_cashReturn;
return dMoney - dReturnMoney;
}
private:
double    m_cashConditon;
double    m_cashReturn;
};
用简单工厂的这个实现:
实现一个简单的工厂类,对创建的对象进行封装;
代码如下:
class  CashFactory 
{
public:
static  CashSuper*  GetCashObject(Promotion_Type eType) 
{
CashSuper* pObject(nullptr);
switch (eType) {
case Promotion_Normal:
pObject = new CashNormal();
break;
case Promotion_0_8:
pObject = new RebateCash(0.8);
break;
case Promotion_300_100:
pObject = new  ReturnCash(300, 100);
break;
}
return pObject;
}
static  void   DestroyCashObject(CashSuper* pCashObject) 
{
if (nullptr != pCashObject) {
delete pCashObject;
pCashObject = nullptr;
}
}
};
用户可以拿这个简单工厂去使用,工厂只是封装了对象的创建工程,对于商场来说促销活动是会常常变化的,
如果有新的需求,就需要去修改工厂的实现;

对于每一种算法,要解决的问题都是同一个,即提供给用户的接口是一致的,只不过每个算法的内部实现不一样;
策略模式就是在这种情况下使用的,用于封装不同的算法,使用算法的人只需要以相同的方式调用就行了;
从而降低了算法类和使用算法类之间的耦合度;
类图如下:


需要添加一个ContextStrategy:

代码如下:

// 策略模式 
// 策略模式是定义一系列算法的方法, 所有的算法完成的都是相同的工作, 接口都是一致的,
// 只是实现不同, 使用算法的类只要相同的方式调用就可以了, 减少了算法类和使用类之间的耦合;
class   CashContext 
{
public:
CashContext(CashSuper* pCashStrategy) 
: m_pCashStrategy(pCashStrategy)
{
}


double   GetResult(double dMoney) 
{
return m_pCashStrategy->GetResult(dMoney);
}


private:
CashSuper*   m_pCashStrategy;
};

用户在使用的时候首先创建一个具体的策略,然后用该策略去创建一个context,就可以使用该context用于产生结果,代码如下:

CashSuper* pCashStrategy{ nullptr };
switch (eType) {
case Promotion_Normal:
pCashStrategy = new CashNormal();
break;
case Promotion_0_8:
pCashStrategy = new RebateCash(0.8);
break;
case Promotion_300_100:
pCashStrategy = new ReturnCash(300, 100);
break;
}
CashContext  context(pCashStrategy);
double dTotal = nNumber * dPrice;
dTotal = context.GetResult(dTotal);

从上面的类图可以看出, 简单工厂模式和策略模式还是很相似的,

对于工厂模式,用户看到是: 基类和工厂类;

对于策略模式,用户看到是: 具体的策略类和策略上下文;

在策略模式中,也可以将策略的创建封装在context中。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值