C++设计模式-使用Qt框架模拟策略模式(Strategy)商场促销
UML图如下:
如果单使用策略模式,会出现这个问题:
客户端判断使用哪个算法!
这里可以用简单工厂与策略模式结合!
运行截图如下:
源码如下:
cash.h
#ifndef CASH_H
#define CASH_H
#include <QString>
class CashSuper{
public:
virtual double acceptCash(double money) = 0;
virtual ~CashSuper(){}
};
class CashNormal: public CashSuper{
public:
double acceptCash(double money);
~CashNormal();
};
class CashRebate: public CashSuper{
public:
CashRebate(const QString moneyRebate);
double acceptCash(double money);
~CashRebate();
private:
double m_moneyRebate;
};
class CashReturn: public CashSuper{
public:
CashReturn(const QString moneyCondition, const QString moneyReturn);
double acceptCash(double money);
~CashReturn();
private:
double m_moneyCondition;
double m_moneyReturn;
};
class CashContext{
public:
CashContext(CashSuper *csuper);
~CashContext();
double getResult(double money);
private:
CashSuper *m_cs;
};
#endif // CASH_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected:
void insertListWidgetItem();
void getCountPrice(double &countPrice);
protected slots:
void submitBtnClicked();
void clearBtnClicked();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
cash.cpp
#include "cash.h"
#include <QDebug>
double CashNormal::acceptCash(double money)
{
return money;
}
CashNormal::~CashNormal()
{
qDebug()<< "CashNormal::~CashSuper() called!";
}
CashRebate::CashRebate(const QString moneyRebate)
{
m_moneyRebate = moneyRebate.toDouble();
}
double CashRebate::acceptCash(double money)
{
return money * m_moneyRebate;
}
CashRebate::~CashRebate()
{
qDebug()<< "CashRebate::~CashRebate() called!";
}
CashReturn::CashReturn(const QString moneyCondition, const QString moneyReturn)
{
m_moneyCondition = moneyCondition.toDouble();
m_moneyReturn = moneyReturn.toDouble();
}
double CashReturn::acceptCash(double money)
{
double result = money;
if(money >= m_moneyCondition)
result = money - (int)(money / m_moneyCondition) * m_moneyReturn;
return result;
}
CashReturn::~CashReturn()
{
qDebug()<< "CashReturn::~CashReturn() called!";
}
CashContext::CashContext(CashSuper *csuper)
{
m_cs = csuper;
}
CashContext::~CashContext()
{
delete m_cs;
}
double CashContext::getResult(double money)
{
return m_cs->acceptCash(money);
}
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "cash.h"
#include <QMessageBox>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("**** IT1995");
ui->rebateComboBox->addItem("正常收费");
ui->rebateComboBox->addItem("满300减100");
ui->rebateComboBox->addItem("打8折");
ui->rebateComboBox->addItem("打5折");
ui->rebateComboBox->addItem("抛出异常");
connect(ui->submitPushButton, SIGNAL(clicked(bool)), this, SLOT(submitBtnClicked()));
connect(ui->clearPushButton, SIGNAL(clicked(bool)), this, SLOT(clearBtnClicked()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::insertListWidgetItem()
{
if(ui->goodsNumLineEdit->text().isEmpty() || ui->goodsPriceLineEdit->text().isEmpty())
throw "goodsNumLineEdit or goodsPriceLineEdit is empty!";
QString goodsNum = ui->goodsNumLineEdit->text();
QString goodsPrice = ui->goodsPriceLineEdit->text();
ui->goodsNumLineEdit->clear();
ui->goodsPriceLineEdit->clear();
ui->listWidget->addItem("商品单价:" + goodsPrice
+ " 商品数量:" + goodsNum
+ " 商品总价:" + QString::number(goodsPrice.toDouble() * goodsNum.toDouble()));
}
void Widget::getCountPrice(double &countPrice)
{
for(int i = 0; i < ui->listWidget->count(); i++){
QStringList list = ui->listWidget->item(i)->text().split("商品总价:");
countPrice += list[list.size() - 1].toDouble();
}
}
void Widget::submitBtnClicked()
{
CashContext *cc = NULL;
try{
if(ui->rebateComboBox->currentText() == "正常收费"){
cc = new CashContext(new CashNormal);
}
else if(ui->rebateComboBox->currentText() == "满300减100"){
cc = new CashContext(new CashReturn("300", "100"));
}
else if(ui->rebateComboBox->currentText() == "打8折"){
cc = new CashContext(new CashRebate("0.8"));
}
else if(ui->rebateComboBox->currentText() == "打5折"){
cc = new CashContext(new CashRebate("0.5"));
}
else{
throw "the text of rebateComboBox is unnormal!";
}
insertListWidgetItem();
double countPrice = 0.0;
getCountPrice(countPrice);
QString priceStr = QString::number(cc->getResult(countPrice));
ui->countPriceLabel->setText("总价:" + priceStr);
}
catch(const char *err){
QMessageBox::information(this, "info", QString(err));
}
if(cc != NULL)
delete cc;
}
void Widget::clearBtnClicked()
{
ui->listWidget->clear();
ui->countPriceLabel->setText("总价:");
}