模型-视图-控制器 (MVC) 并非一种技术,而是软件设计/工程的一个概念。MVC包含三个组成部分,如下图所示

模型

模型直接响应对数据的处理,比如数据库。模型不应依赖其它组成部分,即视图或控制器,换句话说,模型不关心它的数据如何展示和更新。

模型中的数据发生改变,将会发出事件。比如视图模型必须注册模型,以了解数据是如何发生改变的。我们可以在数据改变时定义一个函数回调。

#ifndef COMMON_H
#define COMMON_H #include <string>
using namespace std; typedef void(*dataChangeHandler)(const string &data); #endif // !COMMON_H

dataChangeHandler是一个返回类型为空,含有一个string类型参数的函数指针,模型负责获取数据,并可选择地注册数据改变事件。

#ifndef MODEL_H
#define MODEL_H #include <string>
using namespace std; #include "common.h" class Model
{
public:
Model(const string &strData)
{
this->setData(strData);
} Model() { } string data()
{
return this->m_strData;
} void setData(const string &strData)
{
this->m_strData = strData;
if (this->event != nullptr)
{
this->event(strData);
}
} void registerDataChangeHandler(dataChangeHandler handler)
{
this->event = handler;
} private:
string m_strData = "";
dataChangeHandler event = nullptr;
}; #endif // !MODEL_H

视图

视图知道如何将数据呈现给用户,它需要接触模型并且通常需要定义它的render()方法。

#ifndef VIEW_H
#define VIEW_H #include <iostream>
#include "Model.h" class View
{
public:
View(const Model &model)
{
this->model = model;
} View() {} void setModel(const Model &model)
{
this->model = model;
} void render() {
std::cout << "Model Data = " << model.data() << endl;
}
private:
Model model;
}; #endif // !VIEW_H

控制器

控制器可以让模型更新数据,并且让视图改变数据的呈现,例如显示一个对话框而不是直接输出到控制台。基本来说,它可以获取用户输入,并向视图或模型发送指令。

#ifndef CONTROLLER_H
#define CONTROLLER_H #include "Model.h"
#include "View.h" class Controller
{
public:
Controller(const Model &model, const View &view)
{
this->setModel(model);
this->setView(view);
}
void setModel(const Model &model)
{
this->model = model;
}
void setView(const View &view)
{
this->view = view;
}
void onLoad()
{
this->view.render();
}
private:
Model model;
View view;
}; #endif // !CONTROLLER_H

MVC Demo

有了上面的3个组成类,我们可以通过下面的代码解释MVC。

#include <iostream>
#include "View.h"
#include "Model.h"
#include "Controller.h"
#include "Common.h" using namespace std;
void dataChange(const string &strData)
{
cout << "Data Changes: " << strData << endl;
} int main() {
Model model("Model");
View view(model);
model.registerDataChangeHandler(&dataChange);
Controller controller(model, view);
controller.onLoad();
model.setData("Changes");
return 0;
}

为了避免视图和模型的循环依赖,我们使用函数指针来代表数据改变的事件,而不是用指向成员函数的指针。

编译运行:

Model Data = Model
Data Changes: Changes

model.setData("Changes")触发了模型中的数据改变事件。

最新文章

  1. Fiddler响应post的请求 request body里面填写什么?
  2. Javascript实现二级select联动
  3. 六 mybatis高级映射(一对一,一对多,多对多)
  4. 静态链表 C语言描述
  5. Javacript中(function(){})() 与 (function(){}()) 区别 {转}
  6. 【BZOJ】【2154】Crash的数字表格
  7. 【HDOJ】1754 I Hate It
  8. 解读CSS文本(text)样式
  9. CSS元素 之 float
  10. Android存储之SQLiteDatbase
  11. Sql数据类型转换
  12. 【Linux Shell】uname命令行
  13. python提取网页表格并保存为csv
  14. Java之二分查找算法
  15. MySQL 存储过程错误处理
  16. ruby数组操作方法汇总
  17. Express 体验 路由、模板引擎、中间件
  18. YII2.0使用ActiveForm表单(转)
  19. mysql 执行多线程临时方案
  20. 修改python ide的主题,颜色

热门文章

  1. C# 异步编程(async&amp;await)
  2. PHP实现系统编程(一) --- 网络Socket及IO多路复用【网摘】
  3. loj #10131
  4. Sublime Text 3 C++ 配置
  5. python-图像目标监测(1)识别答题卡
  6. flutter 踩坑小计: amap_base 地图缩放 zoom 设置无效的问题
  7. AtCoder Grand Contest 030 (AGC030) F - Permutation and Minimum 动态规划
  8. UOJ#316. 【NOI2017】泳池 动态规划,Berlekamp-Massey,Cayley-Hamilton定理
  9. Redis恢复数据
  10. ubuntu之路——day10.2单一数字评估指标与满足和优化的评估指标