MVC是一种复合模式,结合了观察者,策略模式和组合模式。
要点:
1.模型使用观察者模式,以便观察者更新,同时保持两者之间解耦。
2.控制器是视图的策略,视图可以使用不同的控制器实现,得到不同的行为。
3.视图使用组合模式实现用户界面,用户界面通常组合了嵌套的组件,像面板,框架和按钮。
4.这些模式携手合作,把MVC模型的三层解耦,这样可以保持设计干净又有弹性。
5.适配器模式用来将新的模型适配成已有的视图和控制器
[img]http://dl.iteye.com/upload/attachment/522476/83a2a81c-040d-3019-b605-7b904f949673.png[/img]
model.h
#ifndef MODEL_H
#define MODEL_H
#include<list>
#include"NumObserver.h"
using namespace std;
class Model{
private:
int number;
list<NumObserver*> lst;
public:
virtual int getNum()const=0;
virtual void setNum(int num)=0;
virtual void registerObserver(NumObserver* o)=0;
virtual void removeObserver(NumObserver* o)=0;
virtual void notifyObserver()=0;
};
class NumModel:public Model{
private:
int number;
list<NumObserver*> lst;
public:
virtual int getNum()const{
return number;
}
virtual void setNum(int num){
number = num;
}
virtual void registerObserver(NumObserver* o){
lst.push_back(o);
}
virtual void removeObserver(NumObserver* o){
lst.remove(o);
}
virtual void notifyObserver(){
list<NumObserver*>::iterator iter=lst.begin();
while(iter!=lst.end()){
(*iter)->update(number);
++iter;
}
}
};
#endif // MODEL_H
NumObserver.h
#ifndef NUMOBSERVER_H
#define NUMOBSERVER_H
class NumObserver{
public:
virtual void update(int num)=0;
virtual int getNum()const=0;
};
class Num:public NumObserver{
private:
int number;
public:
void update(int num){
number = num;
}
int getNum()const{
return number;
}
};
class DoubleNum:public NumObserver{
private:
int number;
public:
void update(int num){
number = num*2;
}
int getNum()const{
return number;
}
};
class SquareNum:public NumObserver{
private:
int number;
public:
void update(int num){
number = num*num;
}
int getNum() const{
return number;
}
};
#endif // NUMOBSERVER_H
NumWidgetViewer.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<boost/scoped_ptr.hpp>
#include"NumController.h"
using namespace boost;
class NumController;
class NumWidgetViewer : public QWidget
{
Q_OBJECT
public:
explicit NumWidgetViewer(NumController* controller,QWidget *parent = 0);
~NumWidgetViewer();
void updateNum(int num,int doubleNum,int squareNum);
protected slots:
void on_decreaseButton_clicked();
void on_increaseButton_clicked();
private:
class NumWidgetViewerUi;
scoped_ptr<NumWidgetViewerUi> mui;
NumController* mController;
};
#endif // WIDGET_H
NumWidgetViewer.cpp
#include "NumWidgetViewer.h"
#include "ui_widget.h"
class NumWidgetViewer::NumWidgetViewerUi:public Ui::Widget{
};
NumWidgetViewer::NumWidgetViewer(NumController* controller,QWidget *parent):
QWidget(parent),mController(controller)
{
//init viewer
mui.reset(new NumWidgetViewerUi);
mui->setupUi(this);
mui->numEdit->setEnabled(false);
mui->DoubleEdit->setEnabled(false);
mui->SquareEdit->setEnabled(false);
}
void NumWidgetViewer::on_decreaseButton_clicked(){
mController->decreaseNum();
update();
}
void NumWidgetViewer::on_increaseButton_clicked(){
mController->increaseNum();
update();
}
void NumWidgetViewer::updateNum(int num, int doubleNum, int squareNum){
mui->numEdit->setText(QString::number(num));
mui->DoubleEdit->setText(QString::number(doubleNum));
mui->SquareEdit->setText(QString::number(squareNum));
}
NumWidgetViewer::~NumWidgetViewer()
{
}
NumController.h
#ifndef NUMCONTROLLER_H
#define NUMCONTROLLER_H
#include"Model.h"
#include"NumWidgetViewer.h"
#include<boost/scoped_ptr.hpp>
using namespace boost;
class NumWidgetViewer;
class NumController{
public:
NumController();
void increaseNum();
void decreaseNum();
void setNum(int num);
void createView();
private:
class NumControllerData;
scoped_ptr<NumControllerData> mData;
scoped_ptr<NumWidgetViewer> mViewer;
};
#endif // NUMCONTROLLER_H
NumController.cpp
#include"NumController.h"
#include"NumObserver.h"
class NumController::NumControllerData{
public:
NumObserver *doubleNum;
NumObserver *squareNum;
NumObserver *num;
Model *model;
int number;
public:
NumControllerData(){
doubleNum = new DoubleNum;
squareNum = new SquareNum;
num = new Num;
model = new NumModel;
model->registerObserver(doubleNum);
model->registerObserver(squareNum);
model->registerObserver(num);
}
};
NumController::NumController()
{
//init model
mData.reset(new NumControllerData);
createView();
}
//init viewer
void NumController::createView(){
mViewer.reset(new NumWidgetViewer(this));
setNum(10);
mViewer->show();
}
void NumController::increaseNum()
{
setNum(mData->model->getNum()+1);
}
void NumController::decreaseNum()
{
setNum(mData->model->getNum()-1);
}
void NumController::setNum(int num)
{
mData->model->setNum(num);
mData->model->notifyObserver();
mViewer->updateNum(mData->num->getNum(),
mData->doubleNum->getNum(),
mData->squareNum->getNum());
}
main.cpp
#include <QtGui/QApplication>
#include "NumController.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
NumController* controller = new NumController;
controller->createView();
return a.exec();
}
[img]http://dl.iteye.com/upload/attachment/522478/f3774b89-64df-3d16-a06f-354b81f3ce20.png[/img]