文章目录
MVC
MVC是一种将应用程序分为三个核心组件的架构模式:
- Model(模型) ------ 负责数据, 不关心数据怎么显示
- View(视图) ------ 负责界面显示,只负责把数据显示出来,
- Controller(控制器) ------ 负责处理用户输入并协调 Model 和 View,用户交互和业务逻辑
通过Controller 把 Model 和 View 进行解耦

MVC 的大致工作流程
用户与 View 交互(例如点击按钮)。
Controller 捕捉到动作,向后端发送数据,后端返回的数据 (修改 Model) Model 改变后,在通知 View 更新显示。
cpp
#include <iostream>
#include <vector>
#include <string>
// --- 1. Model (模型) ---
// 负责存储数据,并在数据改变时通知观察者
class Model {
private:
int data;
public:
Model(int d) : data(d) {}
void setData(int d) {
data = d;
std::cout << "[Model] 数据更新为: " << data << std::endl;
}
int getData() const { return data; }
};
// --- 2. View (视图) ---
// 负责数据的显示
class View {
public:
void render(int data) {
std::cout << "[View] 屏幕显示当前数值: " << data << std::endl;
}
};
// --- 3. Controller (控制器) ---
// 负责逻辑中转
class Controller {
private:
Model& model;
View& view;
public:
Controller(Model& m, View& v) : model(m), view(v) {}
// 模拟用户输入处理
void onUserAction(int newValue) {
std::cout << "[Controller] 接收到用户输入: " << newValue << std::endl;
model.setData(newValue);
updateView();
}
void updateView() {
view.render(model.getData());
}
};
// --- 程序入口 ---
int main() {
// 初始化
Model model(10);
View view;
Controller controller(model, view);
// 初始显示
controller.updateView();
std::cout << "-------------------------------" << std::endl;
// 模拟用户操作:将数值改为 100
controller.onUserAction(100);
return 0;
}
优点与缺点
- 优点
最大的优点已经说过了就是通过Controller 把 Model 和 View 进行解耦,把业务逻辑、数据、界面分离
- 缺点
1️⃣ 所有逻辑都堆到 Controller上了,如 业务逻辑,数据处理,UI控制,结果就是 变成"上帝类,难维护。 久而久之就变成加入MVC架构前的代码臃肿问题,非常难维护。Controller 依赖太多。这个是最明显的缺点。
2️⃣ View 可能直接访问 Model
在小型项目上可以采取MVC架构
随之 引出MVVM 架构
MVVM

- Model(模型) :
表示应用程序的数据负责处理数据的存取、处理和操作,Model并不直接与UI层交互,它只暴露一些接口供ViewModel层调用,使得ViewModel可以获取所需的数据。
- View (视图):
主要负责界面展示和用户交互,例如按钮点击、数据显示等。View 通过数据绑定(Data Binding)与 ViewModel 进行通信,不直接访问 Model,也不包含业务逻辑。通过ViewModel通知来更新
- ViewModel(视图模型):
Model 和 View 之间的桥梁,负责从 Model 中获取数据,并转换为 View 可以直接使用的形式。同时 ViewModel 处理 UI 相关逻辑,调用 Model 完成业务操作,并通过数据绑定机制通知 View 自动更新界面。
SwiftUI 项目非常适合 MVVM,因为页面是状态驱动的
优点
在 MVC 中,Controller 既要处理业务逻辑,又要操作 View 的更新。项目一复杂,Controller 就会变成几千行的"垃圾场"。
MVVM 的做法:引入 ViewModel。它只负责把 Model 的数据转换成 View 需要的格式,不直接操作 UI 控件。逻辑被极大地抽离了。
在 MVC 中,Model 变了,你通常得手动写代码去更新 View(比如label.setText(model.name))MVVM 的做法:通过 Data Binding(数据绑定)。只要 Model 里的数据变了,View 会自动跟着变;用户在界面改了数据,Model 也会自动更新。你再也不用写那堆繁琐的同步代码了。
UI 和业务逻辑分离更清晰
View 更轻,ViewModel 负责状态和逻辑, 不操作UI
由于 C++ 原生不支持像 JavaScript 或 swift 那样的自动监听机制,我们通常使用 观察者模式 或 回调函数 来模拟 ViewModel 对 View 的自动驱动。
cpp
#include <iostream>
#include <string>
#include <functional>
#include <vector>
// --- 1. Model (模型) ---
// 纯粹的数据和业务逻辑
struct UserData {
int score;
};
// --- 2. ViewModel (视图模型) ---
// 它是 View 的抽象,处理逻辑并通知 View 刷新
class CounterViewModel {
private:
UserData model; // 持有 Model
// 模拟数据绑定:当数据变化时执行的回调列表
std::vector<std::function<void(const std::string&)>> scoreChangedCallbacks;
public:
CounterViewModel() { model.score = 0; }
// 绑定接口:View 通过这个接口注册"刷新动作"
void bindScore(std::function<void(const std::string&)> callback) {
scoreChangedCallbacks.push_back(callback);
}
// 业务逻辑:处理用户意图
void incrementScore() {
model.score++;
// 核心:数据改变后,自动通知所有绑定的 View 刷新
std::string displayStr = "当前得分: " + std::to_string(model.score);
for (auto& cb : scoreChangedCallbacks) {
cb(displayStr);
}
}
};
// --- 3. View (视图) ---
// 只负责显示和转发输入,不持有业务逻辑
class CounterView {
private:
CounterViewModel& viewModel;
public:
CounterView(CounterViewModel& vm) : viewModel(vm) {
// 【数据绑定】:告诉 ViewModel,如果数据变了,就执行我的 lambda 表达式
viewModel.bindScore([this](const std::string& uiText) {
this->draw(uiText);
});
}
// 模拟 UI 渲染
void draw(const std::string& text) {
std::cout << "[UI 渲染] " << text << std::endl;
}
// 模拟用户点击按钮
void onButtonClick() {
std::cout << "[UI 事件] 用户点击了增加按钮" << std::endl;
viewModel.incrementScore();
}
};
// --- 程序入口 ---
int main() {
CounterViewModel vm; // 创建逻辑层
CounterView view(vm); // 创建表现层并完成绑定
// 初始状态
std::cout << "程序启动..." << std::endl;
// 模拟用户两次点击
view.onButtonClick();
view.onButtonClick();
return 0;
}