我們通常會一起使用很多種模式,並且在同一個設計解決方案裡面結合它們
深入淺出設計模式, 2nd (p.494)
學習MVC的秘密: 它只是將一些模式擺在一起罷了
深入淺出設計模式, 2nd (p.522)
在這個例子中,我們將使用 C++ 來實現一個簡單的 MVC 架構,用於新增班級學生的編號:
// Model
class StudentModel {
public:
void addStudentID(int id) {
studentIDs.push_back(id);
}
std::vector<int> getStudentIDs() {
return studentIDs;
}
private:
std::vector<int> studentIDs;
};
// View
class StudentView {
public:
void printStudentDetails(std::vector<int> studentIDs) {
std::cout << "Student IDs: ";
for (int id : studentIDs) {
std::cout << id << " ";
}
std::cout << std::endl;
}
};
// Controller
class StudentController {
public:
StudentController(StudentModel* model, StudentView* view) : model(model), view(view) {}
void addStudentID(int id) {
model->addStudentID(id);
view->printStudentDetails(model->getStudentIDs());
}
private:
StudentModel* model;
StudentView* view;
};
// Client (User)
int main() {
StudentModel model;
StudentView view;
StudentController controller(&model, &view);
controller.addStudentID(1);
controller.addStudentID(2);
controller.addStudentID(3);
}
Output:
Student IDs: 1
Student IDs: 1 2
Student IDs: 1 2 3
檔案: widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtSql>
#include <QtGui>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void populateDataItem();
public slots:
void addnew();
void remove();
void save();
private:
Ui::Widget *ui;
QSqlTableModel *model;
QSqlDatabase db;
bool initDatabase();
void closeDatabase();
};
#endif // WIDGET_H
檔案: widget.c
#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
Widget::Widget(QWidget *parent) : QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
initDatabase();
populateDataItem();
connect(ui->deleteButton, SIGNAL(clicked(bool)),this,
SLOT(remove()));
connect(ui->addButton, SIGNAL(clicked(bool)),this,
SLOT(addnew()));
connect(ui->submitButton, SIGNAL(clicked(bool)),this,
SLOT(save()));
}
void Widget::populateDataItem(){
model=new QSqlTableModel(0, db);
model->setTable("books");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();
model->setHeaderData(0, Qt::Horizontal, tr("ISBN"));
model->setHeaderData(1, Qt::Horizontal, tr("Title"));
model->setHeaderData(2, Qt::Horizontal, tr("Edition"));
model->setHeaderData(3, Qt::Horizontal, tr("Publisher"));
model->setHeaderData(4, Qt::Horizontal, tr("Copyright"));
model->setHeaderData(5, Qt::Horizontal, tr("Price"));
model->setHeaderData(6, Qt::Horizontal, tr("Authors"));
ui->tableView->setModel(model);
ui->tableView->setAlternatingRowColors(true);
}
bool Widget::initDatabase(){
db=QSqlDatabase::addDatabase("QMYSQL","MyLibrary");
db.setHostName("localhost");
db.setDatabaseName("test");
db.setUserName("user1");
db.setPassword("secret");
return db.open();
}
void Widget::closeDatabase(){
db.close();
}
Widget::~Widget()
{
closeDatabase();
delete model;
delete ui;
}
void Widget::addnew(){
int row=0;
model->insertRows(row,1);
model->setData(model->index(row,0),ui->edIsbn->text());
model->setData(model->index(row,1),ui->edTitle->text());
model->setData(model->index(row,2),ui->edEdition->text());
model->setData(model->index(row,3),ui->edPublisher->text());
model->setData(model->index(row,4),ui->edCopyright->text());
model->setData(model->index(row,5),ui->dspinPrice->value());
model->setData(model->index(row,6),ui->edAuthors->text());
}
void Widget::remove(){
int row=ui->tableView->currentIndex().row();
if(QMessageBox::question(0,"Delete", "Record no. "
+QString::number(row+1)
+" will be deleted. Are you sure?",
QMessageBox::No,QMessageBox::Yes)==
QMessageBox::Yes){
model->removeRow(row);
}
}
void Widget::save(){
bool flag=model->submitAll();
if(flag==false)
QMessageBox::critical(0,"Failed", "cannot save changes.");
else
QMessageBox::information(0,"success",
"changes saved successfully.");
}
檔案: main.cpp (User Demo)
#include "widget.h"
#include <QApplication>
#include <QStyleFactory>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QApplication::setStyle(QStyleFactory::create("fusion"));
Widget w;
w.show();
return a.exec();
}
Output: