程序运行截图如下:
理论:
面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。
注意:这个模式值解决了对象创建的问题,工厂本身包含了所有收费方式,每一次维护或扩展收费方式都要改动动词,导致代码要重写编译部署,这是个方法,但不是最好的方法!
源码如下:
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 CashFactory{
public:
static CashSuper *createCashAccept(const QString type);
};
#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 - (money / m_moneyCondition) * m_moneyReturn;
return result;
}
CashReturn::~CashReturn()
{
qDebug()<< "CashReturn::~CashReturn() called!";
}
CashSuper *CashFactory::createCashAccept(const QString type)
{
CashSuper *cs = nullptr;
if(type == "正常收费"){
cs = new CashNormal;
}
else if(type == "满300减100"){
cs = new CashReturn("300", "100");
}
else if(type == "打8折"){
cs = new CashRebate("0.8");
}
else if(type == "打5折"){
cs = new CashRebate("0.5");
}
else{
throw "The type is error";
}
return cs;
}
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("CSDN 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()
{
CashSuper *csuper = NULL;
try{
insertListWidgetItem();
double countPrice = 0.0;
csuper = CashFactory::createCashAccept(ui->rebateComboBox->currentText());
getCountPrice(countPrice);
QString priceStr = QString::number(csuper->acceptCash(countPrice));
ui->countPriceLabel->setText("总价:" + priceStr);
}
catch(const char * err){
QMessageBox::information(this, "提示", QString(err));
}
if(csuper != NULL)
delete csuper;
}
void Widget::clearBtnClicked()
{
ui->listWidget->clear();
ui->countPriceLabel->setText("总价:");
}
UML图如下: