Design patterns--代理模式

设计模式之代理模式


我们使用Qt开发大型应用程序时,经常遇见大型程序启动时需要加载一些配置信息、用户末次操作信息,以及算法模型等数据时比较费时,笔者在程序启动时设计欢迎页或加载页等窗体来提示用户程序正在加载某些数据,加载界面运行的时候使用代理模式去读取程序运行所需的数据。

  • 效果演示
  • 代码
cpp 复制代码
#ifndef CONFIGUREBRIDGE_H
#define CONFIGUREBRIDGE_H

#include <QObject>

#pragma pack(push)
#pragma pack(1)
typedef struct s_DataBaseInfo
{
    QString _ip;
    qint16 _port;
    QString _userName;
    QString _pwd;
    QString _dbName;
    qint32 _saveMark;
    qint32 _logMark;

}DataBaseInfo;
#pragma pack(pop)

class ConfigureBridge : public QObject
{
    Q_OBJECT
public:
    static ConfigureBridge *Instance();
    static void Destroy();
private:
    explicit ConfigureBridge(QObject *parent = nullptr);
    ConfigureBridge(const ConfigureBridge &);
    ConfigureBridge &operator=(const ConfigureBridge &);
    ~ConfigureBridge();

private:
    static ConfigureBridge* _instance;

signals:

public:
    DataBaseInfo g_DBInfo;
};

Q_DECLARE_METATYPE(DataBaseInfo)

#endif // CONFIGUREBRIDGE_H

//-----------------------------
#include "configurebridge.h"

ConfigureBridge* ConfigureBridge::_instance = nullptr;

ConfigureBridge *ConfigureBridge::Instance()
{
    if(_instance == nullptr)
    {
        _instance = new ConfigureBridge();
    }
    return _instance;
}

void ConfigureBridge::Destroy()
{
    if(_instance != nullptr)
    {
        delete _instance;
        _instance = nullptr;
    }
}

ConfigureBridge::ConfigureBridge(QObject *parent) : QObject(parent)
{

}

ConfigureBridge::ConfigureBridge(const ConfigureBridge &)
{

}

ConfigureBridge &ConfigureBridge::operator=(const ConfigureBridge &)
{

}

ConfigureBridge::~ConfigureBridge()
{

}
cpp 复制代码
#ifndef LOADDATA_H
#define LOADDATA_H

#include <QObject>
#include <QFile>
#include <QXmlStreamReader>

// 系统配置文件XML
class ReadXml : public QObject
{
    Q_OBJECT
public:
    explicit ReadXml(QObject *parent = nullptr);

    void readSysCfg();
};

class OP_Subject
{

public:
    virtual void readOperatePointsData() = 0;
};

// 工况点数据Dat
class LoadData : public QObject, public OP_Subject
{
    Q_OBJECT
public:
    explicit LoadData(QObject *parent = nullptr);

    void readOperatePointsData() override;
signals:

};

class OP_Proxy : public QObject, public OP_Subject
{
    Q_OBJECT
public:
    explicit OP_Proxy(QObject *parent = nullptr);

    void readOperatePointsData() override;

private:
    LoadData* m_loadData;
};

#endif // LOADDATA_H

//--------------------------------
#include "loaddata.h"
#include <QDataStream>
#include <QDebug>
#include <QTextCodec>
#include <unistd.h>
#include "configurebridge.h"

ReadXml::ReadXml(QObject *parent) : QObject(parent)
{

}

void ReadXml::readSysCfg()
{
    printf("[%s:%s:%d]\n", __FILE__, __FUNCTION__, __LINE__);
    QFile file("system_config.xml");
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        return;
    }

    QXmlStreamReader xmlReader(&file);
    if(xmlReader.hasError())
    {
        qDebug() << "XML error: " << xmlReader.errorString();
        return;
    }

    while (!xmlReader.atEnd() && !xmlReader.hasError())
    {
        xmlReader.readNext();
        if(xmlReader.isStartElement())
        {
            // qDebug() << xmlReader.name().toString();
            if(xmlReader.name().toString() == "ip")
            {
                QString item = xmlReader.readElementText();
                qDebug() << item;
                ConfigureBridge::Instance()->g_DBInfo._ip = item;
            }
            else if(xmlReader.name().toString() == "port")
            {
                QString item = xmlReader.readElementText();
                qDebug() << item;
                ConfigureBridge::Instance()->g_DBInfo._port = item.toUInt();
            }
            else if(xmlReader.name().toString() == "username")
            {
                QString item = xmlReader.readElementText();
                qDebug() << item;
                ConfigureBridge::Instance()->g_DBInfo._userName = item;
            }
            else if(xmlReader.name().toString() == "pwd")
            {
                QString item = xmlReader.readElementText();
                qDebug() << item;
                ConfigureBridge::Instance()->g_DBInfo._pwd = item;
            }
            else if(xmlReader.name().toString() == "dbname")
            {
                QString item = xmlReader.readElementText();
                qDebug() << item;
                ConfigureBridge::Instance()->g_DBInfo._dbName = item;
            }
            else if(xmlReader.name().toString() == "save_mark")
            {
                QString item = xmlReader.readElementText();
                qDebug() << item;
                ConfigureBridge::Instance()->g_DBInfo._saveMark = item.toInt();
            }
            else if(xmlReader.name().toString() == "log_mark")
            {
                QString item = xmlReader.readElementText();
                qDebug() << item;
                ConfigureBridge::Instance()->g_DBInfo._logMark = item.toInt();
            }
        }
        else if(xmlReader.isEndElement())
        {
            // qDebug() << "==End==";
        }
        else if(xmlReader.isCharacters() && !xmlReader.isWhitespace())
        {
            // qDebug() << xmlReader.text().toString();
        }
    }

    file.close();
}

LoadData::LoadData(QObject *parent) : QObject(parent)
{

}

void LoadData::readOperatePointsData()
{
    printf("[%s:%s:%d]\n", __FILE__, __FUNCTION__, __LINE__);
    sleep(2);
    QFile file("op_info.dat");
    if(!file.open(QIODevice::ReadOnly))
    {
        return;
    }

    QString strBinary;
    QTextCodec* codec = QTextCodec::codecForName("UTF-8");
    QDataStream dataStream(&file);
    while (!dataStream.atEnd())
    {
        QByteArray tmpLine = file.readLine();
        strBinary += codec->toUnicode(tmpLine.trimmed());
    }
    file.close();

    qDebug() << strBinary;

    sleep(2);
    qDebug() << "Data loading completed ^_^";
}


OP_Proxy::OP_Proxy(QObject *parent) : QObject(parent)
{
    m_loadData = nullptr;
}

void OP_Proxy::readOperatePointsData()
{
    printf("[%s:%s:%d]\n", __FILE__, __FUNCTION__, __LINE__);
    if(m_loadData == nullptr)
    {
        m_loadData = new LoadData();
    }

    m_loadData->readOperatePointsData();
}
cpp 复制代码
#ifndef SYSTEMCONFIG_H
#define SYSTEMCONFIG_H

#include <QObject>
#include "welcomefrm.h"
#include "loaddata.h"

/**
 * 1、加载系统配置信息
 * 2、加载工况点数据
 */

class SystemConfig : public QObject
{
    Q_OBJECT
public:
    explicit SystemConfig(QObject *parent = nullptr);

    void read_system_config();
    void closeWelPage();

signals:

private:
    WelcomeFrm* m_welFrm;
    ReadXml* m_readXmlCfg;
    OP_Proxy* m_opProxy;
};

#endif // SYSTEMCONFIG_H

//--------------------------------------
#include "systemconfig.h"
#include <QCoreApplication>

SystemConfig::SystemConfig(QObject *parent) : QObject(parent)
{
    m_welFrm = new WelcomeFrm();
    m_readXmlCfg = new ReadXml(this);
    m_opProxy = new OP_Proxy(this);
}

void SystemConfig::read_system_config()
{
    m_welFrm->show();
    QCoreApplication::processEvents();

    m_readXmlCfg->readSysCfg();
    m_opProxy->readOperatePointsData();
}

void SystemConfig::closeWelPage()
{
    m_welFrm->hide();
    m_welFrm->deleteLater();
    m_welFrm = nullptr;
}
cpp 复制代码
#ifndef WELCOMEFRM_H
#define WELCOMEFRM_H

#include <QWidget>

namespace Ui {
class WelcomeFrm;
}

class WelcomeFrm : public QWidget
{
    Q_OBJECT

public:
    explicit WelcomeFrm(QWidget *parent = nullptr);
    ~WelcomeFrm();

    void initSystemCfg();

private:
    Ui::WelcomeFrm *ui;
};

#endif // WELCOMEFRM_H

//------------------------------------
#include "welcomefrm.h"
#include "ui_welcomefrm.h"
#include <QPalette>
#include <QPixmap>

WelcomeFrm::WelcomeFrm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::WelcomeFrm)
{
    ui->setupUi(this);
    //去掉窗口边框
    this->setWindowFlags(Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);

    QPalette pal = this->palette();
    pal.setBrush(QPalette::Background, QBrush(QPixmap(":/res/welcome.jpg")));
    setPalette(pal);

    ui->label->setStyleSheet("QLabel{color: rgb(255,0,255);"
                             "border: 1px solid green; border-radius: 2px;"
                             "font-size: 30px; font-weight:bold;}");

    ui->label->setText("数据加载中...");

    printf("[%s:%s:%d]\n", __FILE__, __FUNCTION__, __LINE__);
}

WelcomeFrm::~WelcomeFrm()
{
    delete ui;
}

void WelcomeFrm::initSystemCfg()
{
}
cpp 复制代码
#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWidget; }
QT_END_NAMESPACE

class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = nullptr);
    ~MainWidget();

private:
    Ui::MainWidget *ui;
};
#endif // MAINWIDGET_H

//--------------------------------
#include "mainwidget.h"
#include "ui_mainwidget.h"
#include "configurebridge.h"
#include <QDebug>

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MainWidget)
{
    ui->setupUi(this);
    ui->textEdit->setReadOnly(true);
    ui->textEdit->setStyleSheet("QTextEdit{background: #033441;"
                                "color:#64eefa;"
                                "border:1px solid #64eefa;"
                                "font-size: 30px;"
                                "font-weight:bold;}");

    ui->textEdit->append(ConfigureBridge::Instance()->g_DBInfo._ip);
    ui->textEdit->append(QString::number(ConfigureBridge::Instance()->g_DBInfo._port));
    ui->textEdit->append(ConfigureBridge::Instance()->g_DBInfo._userName);
    ui->textEdit->append(ConfigureBridge::Instance()->g_DBInfo._pwd);
    ui->textEdit->append(ConfigureBridge::Instance()->g_DBInfo._dbName);
    ui->textEdit->append(QString::number(ConfigureBridge::Instance()->g_DBInfo._saveMark));
    ui->textEdit->append(QString::number(ConfigureBridge::Instance()->g_DBInfo._logMark));
}

MainWidget::~MainWidget()
{
    delete ui;
}
cpp 复制代码
#include <QApplication>
#include <QElapsedTimer>
#include <QMetaType>
#include <unistd.h>
#include "configurebridge.h"
#include "systemconfig.h"
#include "mainwidget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    qRegisterMetaType<DataBaseInfo>("DataBaseInfo");

    // 加载系统的配置数据
    SystemConfig sysCfg;
    sysCfg.read_system_config();

    MainWidget w;
    w.show();
    sysCfg.closeWelPage();

    return a.exec();
}
相关推荐
wrx繁星点点5 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
金池尽干6 小时前
设计模式之——观察者模式
观察者模式·设计模式
也无晴也无风雨6 小时前
代码中的设计模式-策略模式
设计模式·bash·策略模式
肘击鸣的百k路15 小时前
Java 代理模式详解
java·开发语言·代理模式
捕鲸叉16 小时前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
wrx繁星点点16 小时前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
凉辰16 小时前
设计模式 策略模式 场景Vue (技术提升)
vue.js·设计模式·策略模式
菜菜-plus16 小时前
java设计模式之策略模式
java·设计模式·策略模式
暗黑起源喵16 小时前
设计模式-迭代器
设计模式
lexusv8ls600h18 小时前
微服务设计模式 - 网关路由模式(Gateway Routing Pattern)
spring boot·微服务·设计模式