学习笔记:简单工厂模式

2 篇文章 0 订阅
1 篇文章 0 订阅

前天买了《大话设计模式》,开始学习设计模式。从入公司以来,接触了一些Qt的知识,由于上学时只是浅显的学习了C语言,还自学了一点儿Java和C++,都学得很浅显,属于水过地皮都没太湿型的,没写过多少程序,所以Qt也是学得很慢,对于程序的逻辑也经常绕不过弯来,时常觉得自己很笨,后悔当初没有认真的专一的学习一门编程语言。在公司里也是整天无所事事,心中也是很不踏实,觉得自己是光吃饭不干活了。所以从现在起,要加油了努力了。先从每天看完书自己写个相应模式的小例子开始,与Qt结合,坚持写学习笔记,日积月累,相信自己会有长足的进步的。

今天学的是简单工厂模式,写了一个生产汽车各部件的例子。Ui界面如下:

         

功能方面,就是根据生产内容中的选择,点击确定键后在下方的文本框中显示相应的信息。

先写一个没有运用设计模式的例子,然后运用简单工厂模式对其进行改进,然后进行对比分析,最后总结在编程中遇到的一些问题。

1、没有运用设计模式的程序

makecardialog.h

#ifndef MAKECARDIALOG_H
#define MAKECARDIALOG_H

#include <QtGui/QDialog>

class QComboBox;
class QLabel;
class QTextBrowser;
class QPushButton;

class MakeCarDialog : public QDialog
{
    Q_OBJECT

public:
    MakeCarDialog(QWidget *parent = 0);
    ~MakeCarDialog();

private slots:
    void resultText();

private:
    QLabel *kindLabel;
    QComboBox *kindComboBox;
    QLabel *resultLabel;
    QTextBrowser *resultTextBrowser;
    QPushButton *okButton;
};

#endif


 

makecardialog.cpp

#include "makecardialog.h"
#include <QtGui>

MakeCarDialog::MakeCarDialog(QWidget *parent)
    : QDialog(parent)
{
    kindLabel = new QLabel(tr("生产内容:"));
    kindComboBox = new QComboBox;
    kindComboBox -> addItem(tr("大众汽车"));
    kindComboBox -> addItem(tr("别克汽车"));
    okButton = new QPushButton(tr("确定"));
    resultLabel = new QLabel(tr("生产情况:"));
    resultTextBrowser = new QTextBrowser;

    QHBoxLayout *topLayout = new QHBoxLayout;
    topLayout -> addWidget(kindLabel);
    topLayout -> addWidget(kindComboBox, Qt::AlignLeft);
    topLayout -> addWidget(okButton);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout -> addLayout(topLayout);
    mainLayout -> addWidget(resultLabel);
    mainLayout -> addWidget(resultTextBrowser);

    setLayout(mainLayout);
    setWindowTitle(tr("汽车生产V1.0"));

    connect(okButton, SIGNAL(clicked()), this, SLOT(resultText()));
}

void MakeCarDialog::resultText()
{
    quint8 crIndex = kindComboBox -> currentIndex();

    switch(crIndex)
    {
        case 0:
            resultTextBrowser -> append(tr("大众汽车生产中...\n大众汽车生产完毕!"));
            break;
        case 1:
            resultTextBrowser -> append(tr("别克汽车生产中...\n别克汽车生产完毕!"));
            break;
    }
}

MakeCarDialog::~MakeCarDialog()
{

}

main.cpp

#include <QtGui/QApplication>
#include <QTextCodec>
#include "makecardialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
    MakeCarDialog w;
    w.show();

    return a.exec();
}

2、运用简单工厂模式修改后的程序

car.h

#ifndef CAR_H
#define CAR_H

#include <QString>

class Car
{
public:
    virtual QString makeCar();
};

#endif

car.cpp

#include "car.h"
#include <QObject>

QString Car::makeCar()
{
    QString str = QString(QObject::tr(""));
    return str;
}

buick.h

#ifndef BUICK_H
#define BUICK_H

#include "car.h"

class Buick : public Car
{
public:
    virtual QString makeCar();

};

#endif

buick.cpp

#include "buick.h"
#include <QObject>

QString Buick::makeCar()
{
    QString str = QString(QObject::tr("别克汽车生产中...\n"));
    str += QString(QObject::tr("别克汽车生产完毕!"));
    return str;
}

volkswagen.h

#ifndef VOLKSWAGEN_H
#define VOLKSWAGEN_H

#include "car.h"

class Volkswagen : public Car
{
public:
    virtual QString makeCar();
};

#endif

volkswagen.cpp

#include "volkswagen.h"
#include <QObject>

QString Volkswagen::makeCar()
{
    QString str = QString(QObject::tr("大众汽车生产中...\n"));
    str += QString(QObject::tr("大众汽车生产完毕!"));
    return str;
}

carfactory.h

#ifndef CARFACTORY_H
#define CARFACTORY_H

#include <QtGlobal>
#include "car.h"

class CarFactory
{
public:
    Car *creatCar(quint8 index);
};

#endif

carfactory.cpp

#include "car.h"
#include "carfactory.h"
#include "volkswagen.h"
#include "buick.h"

Car *CarFactory::creatCar(quint8 index)
{
    Car *car;
    switch(index)
    {
        case 0:
            car = new Volkswagen;
            break;
        case 1:
            car = new Buick;
            break;
    }

    return car;
}

makecardialog.h

#ifndef MAKECARDIALOG_H
#define MAKECARDIALOG_H

#include <QtGui/QDialog>

class QComboBox;
class QLabel;
class QTextBrowser;
class QPushButton;

class MakeCarDialog : public QDialog
{
    Q_OBJECT

public:
    MakeCarDialog(QWidget *parent = 0);
    ~MakeCarDialog();

private slots:
    void resultText();

private:
    QLabel *kindLabel;
    QComboBox *kindComboBox;
    QLabel *resultLabel;
    QTextBrowser *resultTextBrowser;
    QPushButton *okButton;
};

#endif

makecardialog.cpp

#include "makecardialog.h"
#include "carfactory.h"
#include "car.h"
#include "buick.h"
#include "volkswagen.h"
#include <QtGui>

MakeCarDialog::MakeCarDialog(QWidget *parent)
    : QDialog(parent)
{
    kindLabel = new QLabel(tr("生产内容:"));
    kindComboBox = new QComboBox;
    kindComboBox -> addItem(tr("大众汽车"));
    kindComboBox -> addItem(tr("别克汽车"));
    okButton = new QPushButton(tr("确定"));
    resultLabel = new QLabel(tr("生产情况:"));
    resultTextBrowser = new QTextBrowser;

    QHBoxLayout *topLayout = new QHBoxLayout;
    topLayout -> addWidget(kindLabel);
    topLayout -> addWidget(kindComboBox, Qt::AlignLeft);
    topLayout -> addWidget(okButton);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout -> addLayout(topLayout);
    mainLayout -> addWidget(resultLabel);
    mainLayout -> addWidget(resultTextBrowser);

    setLayout(mainLayout);
    setWindowTitle(tr("汽车生产V2.0"));

    connect(okButton, SIGNAL(clicked()), this, SLOT(resultText()));
}

void MakeCarDialog::resultText()
{
    quint8 currentIndex = kindComboBox -> currentIndex();
    CarFactory *carFactory = new CarFactory;
    Car *car;
    car = carFactory -> creatCar(currentIndex);
    resultTextBrowser -> append(car->makeCar());
}

MakeCarDialog::~MakeCarDialog()
{

}

main.cpp同前,不在重复。

两个版本的程序至此写完。

3、对比分析

未使用简单工厂模式编写的程序,业务逻辑和界面逻辑的耦合度较高。当需要添加新的生产内容时,需要改写makecardialog.cpp文件中的resultText()槽,增加相应的switch分支,这使得界面逻辑也发生了改变,而且当switch分支多到一定数量时,代码重复度也会变得很高,使得维护起来不方便。

而采用简单工厂模式编写的程序,将业务逻辑和界面逻辑分开,当需要增加新的生产内容时,只需要增加相应的子类继承Car类,并在工厂类CarFactory增加相应的switch分支即可,这些都是业务逻辑的内容,跟界面逻辑完全分离。界面方面只需增加下拉菜单的选项即可。

4、编程中遇到的问题

编译的时候出现过一个inaccessible base的错误,经过检查,是因为Volkswagen类和Buick类在继承Car类时,未指明对Car类的继承方式。而C++中类的默认继承方式是private,所以会出现此错误。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值