当前位置: 首页 > article >正文

MVC、MVP和MVVM模式

MVC模式中,视图和模型之间直接交互,而MVP模式下,视图与模型通过Presenter进行通信MVVM则采用双向绑定,减少手动同步视图和模型的工作。每种模式都有其优缺点,适合不同规模和类型的项目

### MVVM 与 MVP/MVC 的区别:

1. **数据绑定**:

- MVVM 强调 View 和 ViewModel 的自动同步。

- MVP/MVC 需要手动更新 View。

2. **View 的主动性**:

- MVVM 中,View 是完全被动的。

- MVP 中,View 需要通过 Presenter 更新。

- MVC 中,View 可以直接监听 Model 的变化。

3. **适用场景**:

- MVVM 更适合需要频繁更新 UI 的场景(如 GUI 应用)。

- MVP/MVC 更适合简单的逻辑控制。

1.MVC模式

  • Model 负责存储和管理数据。

  • View 负责显示数据。

  • Controller 负责处理用户输入并更新模型,然后通知视图更新显示。

1. 模型(Model)

模型负责管理应用程序的数据和业务逻辑。

// model.h
#ifndef MODEL_H
#define MODEL_H

typedef struct {
    int data;
} Model;

void Model_init(Model *model);
void Model_setData(Model *model, int data);
int Model_getData(Model *model);

#endif // MODEL_H
// model.c
#include "model.h"

void Model_init(Model *model) {
    model->data = 0;
}

void Model_setData(Model *model, int data) {
    model->data = data;
}

int Model_getData(Model *model) {
    return model->data;
}

2. 视图(View)

视图负责显示数据给用户。

// view.h
#ifndef VIEW_H
#define VIEW_H

#include "model.h"

typedef struct {
    Model *model;
} View;

void View_init(View *view, Model *model);
void View_display(View *view);

#endif // VIEW_H
// view.c
#include "view.h"
#include <stdio.h>

void View_init(View *view, Model *model) {
    view->model = model;
}

void View_display(View *view) {
    printf("Data: %d\n", Model_getData(view->model));
}

3. 控制器(Controller)

控制器负责处理用户输入并更新模型。

// controller.h
#ifndef CONTROLLER_H
#define CONTROLLER_H

#include "model.h"
#include "view.h"

typedef struct {
    Model *model;
    View *view;
} Controller;

void Controller_init(Controller *controller, Model *model, View *view);
void Controller_updateData(Controller *controller, int data);

#endif // CONTROLLER_H
// controller.c
#include "controller.h"

void Controller_init(Controller *controller, Model *model, View *view) {
    controller->model = model;
    controller->view = view;
}

void Controller_updateData(Controller *controller, int data) {
    Model_setData(controller->model, data);
    View_display(controller->view);
}

4. 主程序

主程序将模型、视图和控制器组合在一起。

// main.c
#include "model.h"
#include "view.h"
#include "controller.h"

int main() {
    Model model;
    View view;
    Controller controller;

    Model_init(&model);
    View_init(&view, &model);
    Controller_init(&controller, &model, &view);

    // 模拟用户输入
    Controller_updateData(&controller, 10);
    Controller_updateData(&controller, 20);

    return 0;
}

5. 输出结果

Data: 10
Data: 20

2.MVP模式

MVP(Model-View-Presenter)是MVC模式的一种变体,它将视图和模型之间的交互通过Presenter(主持人)来协调。

  • Model 负责存储和管理数据。

  • View 负责显示数据,并将用户输入传递给Presenter。

  • Presenter 负责处理用户输入,更新模型,并通知视图更新显示。

与MVC模式不同,MVP模式中视图和模型之间没有直接交互,所有的交互都通过Presenter来协调。这种设计使得视图和模型之间的耦合度更低,更易于测试和维护。

1. 模型(Model)

模型负责管理应用程序的数据和业务逻辑。

// model.h
#ifndef MODEL_H
#define MODEL_H

typedef struct {
    int data;
} Model;

void Model_init(Model *model);
void Model_setData(Model *model, int data);
int Model_getData(Model *model);

#endif // MODEL_H
// model.c
#include "model.h"

void Model_init(Model *model) {
    model->data = 0;
}

void Model_setData(Model *model, int data) {
    model->data = data;
}

int Model_getData(Model *model) {
    return model->data;
}

2. 视图(View)

视图负责显示数据,并将用户输入传递给Presenter。

// view.h
#ifndef VIEW_H
#define VIEW_H

typedef struct {
    void (*displayData)(int data); // 显示数据的回调函数
} View;

#endif // VIEW_H

3. Presenter(主持人)

Presenter负责处理视图的输入,更新模型,并通知视图更新显示

// presenter.h
#ifndef PRESENTER_H
#define PRESENTER_H

#include "model.h"
#include "view.h"

typedef struct {
    Model *model;
    View *view;
} Presenter;

void Presenter_init(Presenter *presenter, Model *model, View *view);
void Presenter_updateData(Presenter *presenter, int data);

#endif // PRESENTER_H
// presenter.c
#include "presenter.h"

void Presenter_init(Presenter *presenter, Model *model, View *view) {
    presenter->model = model;
    presenter->view = view;
}

void Presenter_updateData(Presenter *presenter, int data) {
    // 更新模型
    Model_setData(presenter->model, data);

    // 从模型获取数据并通知视图更新
    int currentData = Model_getData(presenter->model);
    presenter->view->displayData(currentData);
}

4. 主程序

主程序将模型、视图和Presenter组合在一起。

// main.c
#include <stdio.h>
#include "model.h"
#include "view.h"
#include "presenter.h"

// 视图的具体实现
void displayData(int data) {
    printf("Current Data: %d\n", data);
}

int main() {
    Model model;
    View view;
    Presenter presenter;

    // 初始化
    Model_init(&model);
    view.displayData = displayData; // 设置视图的回调函数
    Presenter_init(&presenter, &model, &view);

    // 模拟用户输入
    Presenter_updateData(&presenter, 10);
    Presenter_updateData(&presenter, 20);

    return 0;
}

5.输出结果

Current Data: 10
Current Data: 20

3.MVVM模式

MVVM(Model-View-ViewModel)是一种常用于GUI应用程序的设计模式,它将视图(View)与模型(Model)通过视图模型(ViewModel)进行解耦。MVVM的核心思想是通过数据绑定将视图和视图模型连接起来,但由于C语言本身不支持数据绑定等高级特性,我们需要通过手动方式模拟MVVM的行为。

  • Model 负责存储和管理数据。

  • View 负责显示数据,并将用户输入传递给视图模型。

  • ViewModel 负责将模型的数据转换为视图可以显示的形式,并处理视图的输入。

在MVVM模式中,视图和模型之间没有直接交互,所有的交互都通过视图模型来协调。视图模型通过回调函数通知视图更新显示,从而实现了视图和模型的解耦。

1. 模型(Model)

模型负责管理应用程序的数据和业务逻辑。

// model.h
#ifndef MODEL_H
#define MODEL_H

typedef struct {
    int data;
} Model;

void Model_init(Model *model);
void Model_setData(Model *model, int data);
int Model_getData(Model *model);

#endif // MODEL_H
// model.c
#include "model.h"

void Model_init(Model *model) {
    model->data = 0;
}

void Model_setData(Model *model, int data) {
    model->data = data;
}

int Model_getData(Model *model) {
    return model->data;
}

2. 视图模型(ViewModel)

视图模型负责将模型的数据转换为视图可以显示的形式,并处理视图的输入。

// viewmodel.h
#ifndef VIEWMODEL_H
#define VIEWMODEL_H

#include "model.h"

typedef struct {
    Model *model;
    void (*onDataChanged)(int data); // 数据改变时的回调函数
} ViewModel;

void ViewModel_init(ViewModel *viewModel, Model *model);
void ViewModel_setData(ViewModel *viewModel, int data);
int ViewModel_getData(ViewModel *viewModel);

#endif // VIEWMODEL_H
// viewmodel.c
#include "viewmodel.h"

void ViewModel_init(ViewModel *viewModel, Model *model) {
    viewModel->model = model;
    viewModel->onDataChanged = NULL; // 初始化为空
}

void ViewModel_setData(ViewModel *viewModel, int data) {//非常很重要,关键的一笔!!
    // 更新模型
    Model_setData(viewModel->model, data);

    // 通知视图数据已改变
    if (viewModel->onDataChanged != NULL) {
        viewModel->onDataChanged(data);
    }
}

int ViewModel_getData(ViewModel *viewModel) {
    return Model_getData(viewModel->model);
}

3. 视图(View)

视图负责显示数据,并将用户输入传递给视图模型。

// view.h
#ifndef VIEW_H
#define VIEW_H

#include "viewmodel.h"

typedef struct {
    ViewModel *viewModel;
} View;

void View_init(View *view, ViewModel *viewModel);
void View_display(View *view);
void View_userInput(View *view, int data);

#endif // VIEW_H
// view.c
#include "view.h"
#include <stdio.h>

// 数据改变时的回调函数
static void onDataChanged(int data) {
    printf("Data Updated: %d\n", data);
}

void View_init(View *view, ViewModel *viewModel) {
    view->viewModel = viewModel;
    viewModel->onDataChanged = onDataChanged; // 设置回调函数
}

void View_display(View *view) {
    int data = ViewModel_getData(view->viewModel);
    printf("Current Data: %d\n", data);
}

void View_userInput(View *view, int data) {
    // 将用户输入传递给视图模型
    ViewModel_setData(view->viewModel, data);
}

4. 主程序

主程序将模型、视图模型和视图组合在一起。

// main.c
#include "model.h"
#include "viewmodel.h"
#include "view.h"

int main() {
    Model model;
    ViewModel viewModel;
    View view;

    // 初始化
    Model_init(&model);
    ViewModel_init(&viewModel, &model);
    View_init(&view, &viewModel);

    // 显示初始数据
    View_display(&view);

    // 模拟用户输入
    View_userInput(&view, 10);
    View_userInput(&view, 20);

    return 0;
}

5. 输出结果

Current Data: 0
Data Updated: 10
Data Updated: 20

**在deep seek协助下

 

 


http://www.kler.cn/a/530555.html

相关文章:

  • 恢复二叉搜索树(99)
  • Spring Boot - 数据库集成06 - 集成ElasticSearch
  • JavaFX - 3D 形状
  • 【Linux系统】信号:信号保存 / 信号处理、内核态 / 用户态、操作系统运行原理(中断)
  • C++11新特性之范围for循环
  • 数据结构与算法之栈: LeetCode 641. 设计循环双端队列 (Ts版)
  • 刷题记录 动态规划-3: 70. 爬楼梯
  • SpringMVC拦截器详解:原理、使用与配置
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.4 索引优化:避免意外复制的高效技巧
  • deepseek使用教程
  • 力扣 347. 前 K 个高频元素
  • Baklib赋能企业提升内容中台构建效率的全新路径解析
  • 基于人脸识别的课堂考勤系统
  • 【系统迁移】将系统迁移到新硬盘中(G15 5520)
  • 高清种子资源获取指南 | ✈️@seedlinkbot
  • 第六篇:事务与并发控制
  • 算法【混合背包】
  • 深入探索 Android 技术:从基础到前沿
  • 向上管理的必要性
  • 本地部署DeepSeek 多模态大模型Janus-Pro-7B
  • C++ 常用排序算法
  • 音视频入门基础:RTP专题(5)——FFmpeg源码中,解析SDP的实现
  • XML DOM 节点信息
  • 眼见着折叠手机面临崩溃,三星计划增强抗摔能力挽救它
  • 【LeetCode 刷题】回溯算法-分割问题
  • 如何本地部署DeepSeek?DeepThink R1 本地部署全攻略:零基础小白指南。