可视门禁中的MVC模式

来源:互联网 发布:百度推广如何优化 编辑:程序博客网 时间:2024/05/19 12:13

可视门禁中的MVC模式

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用于组织代码用一种业务逻辑和数据显示分离的方法 。MVC开始是存在于Desktop程序中的,M是指数据模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。

       在开发可视门禁项目,我需要将数据逻辑处理和图形显示两部分代码分离,这样利于分工,也利于某个模块的功能转换,因此找到了MVC模式(如一般开发方式的图1和MVC开发方式的图2)。

从功能角度来讲,MVC能够满足项目的需求了。但MVC既然是属于项目的架构,那真正的MVC完成的功能绝不仅仅是代码分离,而且还应该是针对项目做更周全的代码管理。网上google了很多资料,但大多是阐述MVC模式的理念,很少可以直接参考的代码。那就只好自己去实现自己的MVC模式了,说是MVC模式,其实更准确理解就是数据处理层(module)和图形显示层(view)的数据传递。MVC整个代码是由三部分组成:(M)module.cpp module.h,(V)view.cppview.h, (C)control.cpp control.h,下面就看怎么实现的。

1.control是框架的核心,其主要负责建立M与C、V与C的相互函数调用接口。

control.h:#ifndef _CONTROL_H_#define _CONTROL_H_#include "module.h"#include "view.h"#include "typedef.h"class Control {public:  Control() {}  virtual ~Control() {}  void InitControl(Module* module, View* view);  void InitProgram();  void DestroyProgram();   view_->HandleEvent(event, data, param);   }  void SendToModule(int event, int data, void* param) {      module_->HandleEvent(event, data, param);  }  static Control* Instance();private:  Module *module_;  View   *view_;  static Control *control_;  static void HandleEvent(int event, int data, void *param);  void InitModule();  void InitView();};#endif

如control.h所示,需包含module.h和view.h头文件,因为C->V和C->M的调用是直接调用M和V的函数,如:

void SendToModule(int event, int data, void* param) { 

   module_->HandleEvent(event, data, param);

  }

至于V->C和M->C的调用就稍微麻烦了。首先是C的接口函数HandleEvent(每个模块只有一个接口,都是HandleEvent,因为在不同类,当然也不会函数同名了)是静态函数,因为静态函数才能取到函数地址。

void Control::InitControl(Module* module, View* view){  assert(module!= NULL);  assert(view !=NULL);   module_ =module;  view_ = view;  module_->SetNotify(HandleEvent); view_->SetNotify(HandleEvent);}

InitControl函数调用module_->SetNotify(HandleEvent);和view_->SetNotify(HandleEvent);这里的HandleEvent是control的函数接口,而SetNotify是module和view类的成员函数,负责将control的HandleEvent的函数地址保存下来,当V->C发送信息时,就直接调用函数地址。这里需要定义一个函数指针变量,然后赋值于它,才能保存下来。到这里基本上建立了模块之间的通信接口。

看一下view.h文件:

#ifndef _VIEW_H_#define _VIEW_H_#include <iostream>#include "typedef.h"class View {public:  virtual ~View() {}  void SetNotify(NOTIFY notify)  { notify_ = notify; }  void SendToControl(int event, int data, void *param);  virtual void HandleEvent(int event, int data, void* param) = 0; private:  NOTIFY notify_;};#endif /* _VIEW_H_*/

刚才说了需要定义函数指针变量存放control的HandleEvent,notify_就是这个变量了。另外需要指出的是view模块的函数接口HandleEvent是一个纯虚函数,也就是项目中实际图形处理的类需要继承view这个类,然后实现这个函数。这样有个好处就是实现了框架部分(mvc)和具体的项目代码分离,也可以实现多个图形类的扩展。module部分也是同理。

       最后说说怎么应用了,首先是main启动MVC,然后调用各个模块之间工作。

以可视门禁项目中的门口机为例:main函数只调用了DoorMachine函数,函数如下:

#include "module_door.h"  void DoorMachine()  {    Control *ctrl = Control::Instance();    View *view_door = new ViewDoor;    Module *module_door = new ModuleDoor;     ctrl->InitControl(module_door, view_door);    ctrl->InitProgram();    ctrl->SendToView(ACCE_V_POLL, 0, NULL);     cout << "appemd to destroy program" << endl;    ctrl->DestroyProgram();     delete view_door;    delete module_door;    delete ctrl;  }

       首先是newMVC三部分的对象,control在项目中是只有一份的,所以这里用了设计模式中的单一模式去生成对象。ViewDoor和ModuleDoor分别是View和Module类的派生类。InitControl函数上面有提到,功能就是建立MVC的通信接口。InitProgram()功能就是分别向ViewDoor和ModuleDoor发出Init信号,初始化各自部分功能,比如ViewDoor是加载控件,显示第一个页面,ModuleDoor加载系统的一些参数。SendToView(ACCE_V_POLL, 0, NULL);就是让主线程循环做某些事。当获取到程序退出的信号,线程会跳出这个循环,执行DestroyProgram();也即让ViewDoor和ModuleDoor做退出处理工作,最后销毁MVC三个对象。

PS:由于本人刚毕业一年,学习c++也才两个月,对MVC模式理解乃至代码的编写肯定存在很多的问题,如您发现什么问题,请发邮件或留言告诉我,我好更正博文,以免误人子弟。邮箱:730024858@qq.com


原创粉丝点击