架构设计理念
-
MVC、MVP、MVVM三种架构设计模式都是为了解决UI页面与逻辑代码分离而产生的;
-
MVC模式的特点在于实现关注点分离,即应用程序中的数据模型与业务和展示逻辑解耦。在客户端web开发中,就是将模型(M-数据、操作数据)、视图(V-显示数据的HTML元素)之间实现代码分离,松散耦合,使之成为一个更容易开发、维护和测试的客户端应用程序。
-
本文将具体介绍最基础的MVC架构实现原理。
MVC架构介绍
Model(模型)
- 模型代表一个存取数据的对象,它也可以带有逻辑,在数据变化时更新控制器。
View(视图)
- 视图代表模型包含的数据的可视化。
Controller(控制器)
- 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。
MVC架构利弊
利好:
-
降低代码耦合性。视图层(View)和业务层(Controller)分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码,同样,一个应用的业务流程或者业务规则的改变只需要改动MVC的模型层即可。因为模型与控制器和视图相分离,所以很容易改变应用程序的数据层和业务规则;
-
有利于分工合作。业务逻辑与视图界面的分离可以让开发人员更加集中精力于自己的模块上;
-
有利于组件的重用。如控制层可独立成一个能用的组件,表示层也可做成通用的操作界面。可以为一个模型在运行时同时建立和使用多个视图。
-
有利于软件工程化管理。由于不同的层各司其职,每一层不同的应用具有某些相同的特征,有利于通过工程化、工具化管理程序代码。
弊端:
-
没有明确的定义,增加理解难度
完全理解MVC并不是很容易。使用MVC需要精心的计划,由于它的内部原理比较复杂,所以需要花费一些时间去思考。同时由于模型和视图要严格的分离,这样也给调试应用程序带来了一定的困难。每个构件在使用之前都需要经过彻底的测试。 -
增加系统结构和实现的复杂性
对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。 -
视图对模型数据的低效率访问
依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。 -
一般高级的界面工具或构造器不支持模式
改造这些工具以适应MVC需要和建立分离的部件的代价是很高的,会造成MVC使用的困难。
C++代码实现
Model实现
StudentModel.h文件
#pragma once
#include <string>
using namespace std;
//模型类,用于数据存储,暴露数据操作接口
class StudentModel
{
private:
int age;
string name;
public:
void setStudentName(string name);
void setStudentAge(int age);
int getStudentAge();
string getStudentName();
};
StudentModel.cpp文件
#include "StudentModel.h"
void StudentModel::setStudentAge(int age) {
this->age = age;
}
void StudentModel::setStudentName(string name) {
this->name = name;
}
int StudentModel::getStudentAge() {
return this->age;
};
string StudentModel::getStudentName() {
return this->name;
};
View实现
StudentView.h文件
#pragma once
#include "StudentModel.h"
#include <iostream>
#include <string>
using namespace std;
//视图View类StudentView
class StudentView
{
public:
void printStudentInfo(int age, string name);
};
StudentView.cpp文件
#include "StudentView.h"
void StudentView::printStudentInfo(int age, string name) {
cout << "**********Name:" << name << "************" << endl;;
cout << "**********Age:" << age << "************" << endl;;
}
Controller实现
StudentController.h文件
#pragma once
#include "StudentModel.h"
#include "StudentView.h"
using namespace std;
//控制器类,控制数据流向
class StudentController
{
private:
StudentModel* model;
StudentView* view;
public:
//绑定视图与模型
StudentController(StudentModel* model, StudentView* view);
// 更新视图
void updateView();
//数据操作
void setStudentName(string name);
string getStudentName();
void setStudentAge(int age);
int getStudentAge();
};
StudentController.cpp文件
#include "StudentController.h"
StudentController::StudentController(StudentModel* model, StudentView* view) {
this->model = model;
this->view = view;
}
//更新视图
void StudentController::updateView() {
int age = this->model->getStudentAge();
string name = this->model->getStudentName();
this->view->printStudentInfo(age, name);
}
//数据操作
void StudentController::setStudentName(string name) {
this->model->setStudentName(name);
}
string StudentController::getStudentName() {
return this->model->getStudentName();
}
void StudentController::setStudentAge(int age) {
this->model->setStudentAge(age);
}
int StudentController::getStudentAge() {
return this->model->getStudentAge();
}
MVC设计的争议的之处
在互联网上,大家对于MVC的理解总体都是围绕Model-Controller-View产生的。但是不同的设计师对于都三者之间的细节问题还是存在不同的见解:
- 有的设计者认为用户直接操作的是Controller控制器,控制器操作Model,再由Model更新视图;
如下图
- 有的设计者认为用户操作的是View视图,通过View将数据流向Controller再对Model进行数据操作:
即用户操作->View(负责接收用户的输入操作)->Controller(业务逻辑处理)->Model(数据持久化)->View(将结果反馈给View)。
个人认为两种观点虽有争议之处但设计理念相同,所以不影响MVC架构的总体设计。
如若文中描述错误,敬请指导。争议之处欢迎大家讨论