MVVM(Model-View-ViewModel)软件框架可以有效分离用户界面和业务逻辑,提升代码的可维护性和可测试性。下面我们简要的实现一个MVVM框架示例,并说明其特点和优势。
框架结构
- Model(模型):负责数据和业务逻辑。
- View(视图):负责UI显示,通常是继承自QWidget的类。
- ViewModel(视图模型):充当View和Model之间的桥梁,处理业务逻辑并提供给View所需的数据。
示例代码
Model
// DataModel.h
#ifndef DATAMODEL_H
#define DATAMODEL_H
#include <QObject>
#include <QString>
class DataModel : public QObject {
Q_OBJECT
Q_PROPERTY(QString data READ data WRITE setData NOTIFY dataChanged)
public:
explicit DataModel(QObject *parent = nullptr) : QObject(parent), m_data("") {}
QString data() const {
return m_data;
}
void setData(const QString &data) {
if (m_data != data) {
m_data = data;
emit dataChanged();
}
}
signals:
void dataChanged();
private:
QString m_data;
};
#endif // DATAMODEL_H
ViewModel
// ViewModel.h
#ifndef VIEWMODEL_H
#define VIEWMODEL_H
#include <QObject>
#include "DataModel.h"
class ViewModel : public QObject {
Q_OBJECT
Q_PROPERTY(QString data READ data WRITE setData NOTIFY dataChanged)
public:
explicit ViewModel(DataModel *model, QObject *parent = nullptr)
: QObject(parent), m_model(model) {
connect(m_model, &DataModel::dataChanged, this, &ViewModel::dataChanged);
}
QString data() const {
return m_model->data();
}
void setData(const QString &data) {
if (m_model->data() != data) {
m_model->setData(data);
}
}
signals:
void dataChanged();
private:
DataModel *m_model;
};
#endif // VIEWMODEL_H
View
// MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLineEdit>
#include <QLabel>
#include "ViewModel.h"
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(ViewModel *viewModel, QWidget *parent = nullptr)
: QMainWindow(parent), m_viewModel(viewModel) {
setupUI();
connect(m_viewModel, &ViewModel::dataChanged, this, &MainWindow::updateUI);
}
private:
void setupUI() {
m_inputField = new QLineEdit(this);
m_label = new QLabel(this);
setCentralWidget(new QWidget(this));
QVBoxLayout *layout = new QVBoxLayout(centralWidget());
layout->addWidget(m_inputField);
layout->addWidget(m_label);
connect(m_inputField, &QLineEdit::textChanged, m_viewModel, &ViewModel::setData);
updateUI();
}
void updateUI() {
m_label->setText(m_viewModel->data());
}
ViewModel *m_viewModel;
QLineEdit *m_inputField;
QLabel *m_label;
};
#endif // MAINWINDOW_H
主程序
// main.cpp
#include <QApplication>
#include "DataModel.h"
#include "ViewModel.h"
#include "MainWindow.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
DataModel dataModel;
ViewModel viewModel(&dataModel);
MainWindow mainWindow(&viewModel);
mainWindow.show();
return app.exec();
}
特点与优势
- 分离关注点:通过将UI逻辑和业务逻辑分离,MVVM框架使得代码更加清晰和易于维护。
- 双向数据绑定:View和ViewModel之间的双向绑定,使得UI自动更新以反映数据变化,而不需要手动同步。
- 可测试性:由于业务逻辑被隔离在ViewModel和Model中,这些部分更容易进行单元测试。
- 代码重用:ViewModel可以在不同的View中重用,从而提高代码的复用性。
- 增强的可维护性:通过将逻辑分层,代码更具模块化,使得团队合作和代码维护更加高效。
这个MVVM框架示例展示了如何在Qt Widget中实现MVVM模式,并介绍了其主要特点和优势。在实际项目中,可以根据需要进一步扩展和调整这个框架。
说明:
- **Qt Widgets**:适用于传统桌面应用,代码结构清晰,但视图和逻辑分离不如Qt Quick彻底。
- **Qt Quick**:视图和逻辑完全分离,适合现代移动和桌面应用,界面更加灵活和美观。