可视门禁中的MVC模式

本文介绍了一种基于MVC模式的可视门禁系统开发方案。MVC(Model-View-Controller)是一种软件架构模式,有助于实现业务逻辑与数据显示的分离。文章详细解释了如何在可视门禁项目中应用MVC模式,包括各组件的具体实现及通信机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可视门禁中的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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值