4.策略模式

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值