23种设计模式 -----Day02:策略模式

目录

策略模式

        基本简介

        使用场景

        应用实例        

        优点

        缺点

实例

Strategy头文件

Strategy源文件

         context上下文

客户端代码

结合简单工厂模式的策略模式

        context上下文

         客户端


策略模式

        基本简介

        策略模式(StrategyModel)是一种 定义一系列算法 的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以 以相同的方式 调用所有的算法,减少了各种算法类与使用算法类之间的耦合[DPE]。

        使用场景

        一个系统有许多类,区分他们的只是直接行为不同时。

        应用实例        

        出行方式,自行车、汽车等,每一种出行方式都是一个策略

        商场促销方式,打折、满减等

        优点

         减少了各种算法类与使用算法类之间的耦合[DPE]

        策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能[DP]

        缺点

        策略类数量会增多,每个策略都是一个类,复用的可能性很小

        所有的策略类都需要对外暴露

※如果一个系统的策略多于四个,就需要考虑使用混合模式来解决策略类膨胀的问题

实例

        本实例还是基于商场收银软件(qt实现),相关内容见day01中

        

        Strategy头文件

#include<QString>
/**
  * @brief 现金收费抽象类、抽象基类
  * @param
  * @return
*/
class CashSuper{
public:
    /**
  * @brief 现金收取类的纯虚函数,收取现金
  * @param 原价
  * @return 当前价
*/
    virtual double AcceptCash(double money)=0;
};

/**
  * @brief 正常收费子类
  * @param
  * @return
*/
class CashNormal:public CashSuper{
public:
    //正常收费,原价返回
   double AcceptCash(double money) override;
};

/**
  * @brief 打折收费子类
  * @param
  * @return
*/
class CashRebate:public CashSuper{
public:
    CashRebate(double moneyRebate);//打折收费,初始化时输入折扣率
    double AcceptCash(double money) override;

private:
    double moneyRate=1;
};
/**
  * @brief 返利收费子类,初始化时输入返利条件和返利值
  * @param 返利条件moneyCondition 返利值moneyReturn
  * @return
*/
class CashReturn:public CashSuper{
public:
    CashReturn(double moneyCondition,double moneyReturn);
    double AcceptCash(double money) override;
private:
    double moneyCondition=0.0;
    double moneyReturn=0.0;
};

Strategy源文件

double CashNormal::AcceptCash(double money)
{
    return money;
}
CashRebate::CashRebate(double moneyRebate)
{
    if(moneyRebate>1||moneyRebate<0){
        throw "rate error";
    }
    this->moneyRate=moneyRebate;
}
double CashRebate::AcceptCash(double money)
{
    return money*moneyRate;
}
CashReturn::CashReturn(double moneyCondition, double moneyReturn)
{
    this->moneyCondition=moneyCondition;
    this->moneyReturn=moneyReturn;
}
double CashReturn::AcceptCash(double money)
{
    double result=money;
    if(money>=moneyCondition){
        result=money-moneyReturn;
    }
    return result;
}

context上下文

#include"Strategy.h"
/**
  * @brief  上下文    策略模式实现
  * @param
  * @return
*/
class CashContext
{
public:
    CashContext(CashSuper* csuper);

    /**
  * @brief 根据收费策略的不同,获得计算结果
  * @param   原价
  * @return   折扣后的价格
*/
    double getResult(double money);

private:
    CashSuper* cs;
};
#include "cashcontext.h"


CashContext::CashContext(CashSuper* csuper)
{
    this->cs=csuper;
}

double CashContext::getResult(double money)
{
    return cs->AcceptCash(money);
}

客户端代码

void Widget::on_btn_ok_clicked()//点击确定槽函数
{
    double total=0.00;//声明一个double变量total来计算总计
    double price=ui->line_Price->text().toDouble();//lineEdit获取price
    double num=ui->line_Num->text().toDouble();//lineEdit获取num
    total=num*price;//获取合计


    CashContext *cs=nullptr;
    switch (ui->comboBox->currentIndex()) {
    case 0:
        cs=new CashContext(new CashNormal());  //正常收费
        break;
    case 1:
        cs=new CashContext(new CashReturn(300,100)); //满300减100
        break;
    case 2:
        cs=new CashContext(new CashRebate(0.8)); //打8折
        break;
    case 3:
        cs=new CashContext(new CashRebate(0.5));//打五折
        break;
    case 4:
        cs=new CashContext(new CashReturn(500,200));//满500减200
        break;
    default:
        break;
    }
    total=cs->getResult(total);



    ui->listWidget->addItem("单价:"+ui->line_Price->text()+
                            " 数量:"+ui->line_Num->text()+
                            " "+ui->comboBox->currentText()+
                            " 合计:"+QString::number(total));//添加到啊listWidget中
    ui->labShowPrice->setText(QString::number(total));//显示到lab中。
}

结合简单工厂模式的策略模式

        利用简单工厂将判断的过程从客户端程序转移走,实现算法和客户端分离。

        context上下文

#include"Strategy.h"
/**
  * @brief  上下文    策略模式实现
  * @param
  * @return
*/
class CashContext
{
public:
    CashContext(int type);

    /**
  * @brief 根据收费策略的不同,获得计算结果
  * @param   原价
  * @return   折扣后的价格
*/
    double getResult(double money);

private:
    CashSuper* cs;
};
#include "cashcontext.h"


CashContext::CashContext(int type)
{
    switch (type) {
    case 0:
        cs= new CashNormal();  //正常收费
        break;
    case 1:
        cs=new CashReturn(300,100); //满300减100
        break;
    case 2:
        cs=new CashRebate(0.8); //打8折
        break;
    case 3:
        cs=new CashRebate(0.5);//打五折
        break;
    case 4:
        cs=new CashReturn(500,200);//满500减200
        break;
    default:
        break;
    }
}

double CashContext::getResult(double money)
{
    return cs->AcceptCash(money);
}

         客户端


void Widget::on_btn_ok_clicked()//点击确定槽函数
{
    double total=0.00;//声明一个double变量total来计算总计
    double price=ui->line_Price->text().toDouble();//lineEdit获取price
    double num=ui->line_Num->text().toDouble();//lineEdit获取num
    total=num*price;//获取合计

//根据下拉框吗,将相应的算法的索引传入到CashContext对象中
    CashContext *cs=new CashContext(ui->comboBox->currentIndex());  
    total=cs->getResult(total);



    ui->listWidget->addItem("单价:"+ui->line_Price->text()+
                            " 数量:"+ui->line_Num->text()+
                            " "+ui->comboBox->currentText()+
                            " 合计:"+QString::number(total));//添加到啊listWidget中
    ui->labShowPrice->setText(QString::number(total));//显示到lab中。
}

void Widget::on_btn_ok_2_clicked()
{
    ui->listWidget->clear();
    ui->labShowPrice->setText("0.00");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值