为了解决一个类实现所有功能的缺陷,我们把application分为2个部分。一个部分业务逻辑,一个部分视觉渲染和交互。这2个类在学术上被称为document view 或者 model

delegate。

   Document类用来处理业务逻辑,和视觉渲染、GUI事件没有一点关系。它简单的存储应用程序的状态,提供接口获得状态并根据应用程序规则改变状态。另外,提供机制告知相关对象,应用程序状态改变。

  View类处理事件和图像渲染。提供对 Document类的操作,界面改变和 Document类中状态改变同步。

   Document View设计模式实现状态和图像显示分离,它们能单独的改变。Document类成为 non-GUI单元,能单独的工作和检测。任何View通过notification system保持和Document内容一致,并根据Document内容 负责图像呈现和用户交互。

  这种设计消除了一些对单个类实现的担忧,对状态和业务逻辑的测试变得更容易:通过调用Document类中的方法。此Document对象现在是独立的,如果需要的话,可以和不同的View工作。代价就是告知View,Document中状态改变(notification system)。

代码如下:

model.h

#include <QSet>
#include <view.h> class View; class Model
{
public:
Model();
int getClickTimes() const;
void setClickTimes(int value);
void incrementClickTimes();
void addListener(View *v);
void removeListener(View *v); private:
int m_clickTimes;
QSet<View *> listeners; //set容器避免重复
void notifyListener();
}; #endif // MODEL_H

model.cpp

#include "model.h"

Model::Model()
{
m_clickTimes = ;
notifyListener();
} int Model::getClickTimes() const
{
return m_clickTimes;
} void Model::setClickTimes(int value)
{
if(m_clickTimes != value)
m_clickTimes = value;
notifyListener();
} void Model::incrementClickTimes()
{
m_clickTimes++;
notifyListener();
} void Model::addListener(View *v)
{
listeners.insert(v);
notifyListener();
} void Model::removeListener(View *v)
{
listeners.remove(v);
} void Model::notifyListener()
{
foreach (View *v, listeners) {
v->notify();
}
}

view.h

#ifndef VIEW_H
#define VIEW_H #include <QPushButton>
#include <model.h> class Model; class View : public QPushButton
{
Q_OBJECT
public:
explicit View(QWidget *parent = );
void notify(); protected:
void mouseReleaseEvent(QMouseEvent *e); private:
Model *model;
}; #endif // VIEW_H

view.cpp

#include "view.h"

View::View(QWidget *parent) :
QPushButton(parent)
{
model = new Model();
model->addListener(this);
} void View::mouseReleaseEvent(QMouseEvent *e)
{
model->incrementClickTimes();
} void View::notify()
{
setText(QString::number(model->getClickTimes()));
}

main.cpp

#include <view.h>
#include <QApplication> int main(int argc, char *argv[])
{
QApplication a(argc, argv);
View v;
v.show(); return a.exec();
}

思考:

1.Model类只处理数据,View类处理事件和如何显示程序。

2.Model类中有一个容器 listeners,存放需要显示数据的类,每当应用程序状态改变时(m_clickTimes改变),告诉那些类,应用程序状态改变啦!

3.View类 mouseRelease函数处理事件,notify函数显示数据。

最新文章

  1. c#编程基础之ref、out参数
  2. AngularJs中,如何在render完成之后,执行Js脚本
  3. 解决python字典结构内存暴涨问题
  4. 能看到U盘占用内存,但看不到文件
  5. XML数据源快速开发框架——XmlFramwork
  6. Ubuntu 14.04远程登录服务器--ssh的安装和配置
  7. PHP Date/Time 函数
  8. 站点搭建从零開始(四) server的配置
  9. Java设计模式:代理模式(一)
  10. ROC曲线的计算
  11. 浅谈Java线程安全
  12. webpack实践笔记
  13. MySQL在高内存、IO利用率上的几个优化点
  14. mybatis学习 -每天一记 通用mapper 关于UUID回显的配置
  15. Java抽象类简单学习
  16. shell printf命令:怎样格式化输出语句
  17. Linux 快速删除已输入的命令
  18. ROS知识(20)----SLAM资源集合
  19. Redis从入门到精通:中级篇(转)
  20. InlineModelAdmin

热门文章

  1. 201621123014《Java程序设计》第十三周学习总结
  2. 使用NSUserDefaults保存自定义对象(转)
  3. UVA 11605 Lights inside a 3d Grid
  4. ACC 001 C - Shorten Diameter 图论
  5. RabbitMQ用户角色及权限控制(不错)
  6. 11.Selenium+Python案例--百度
  7. 在系统学习javaEE开发的颠覆者Springboot时遇到的localhost无法访问的问题
  8. jquery-post 异常
  9. Surface Pro 4远程桌面分辨率问题
  10. C语言第二次实验作业