MVC、MVP和MVVM模式

news/2025/2/3 19:44:34 标签: c++

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.niftyadmin.cn/n/5841029.html

相关文章

LeetCode:63. 不同路径 II

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;63. 不同路径 II 给定一个 m x n 的整数数组 grid。一个机器人初始位于 左上角&#xff08;即 grid[0][0]…

Python - pyautogui库 模拟鼠标和键盘执行GUI任务

安装库&#xff1a; pip install pyautogui 导入库&#xff1a;import pyautogui 获取屏幕尺寸&#xff1a; s_width, s_height pyautogui.size() 获取鼠标当前位置&#xff1a; x, y pyautogui.position() 移动鼠标到指定位置&#xff08;可以先使用用上一个函数调试获取当…

【Elasticsearch】_all 查询

在 Elasticsearch 中&#xff0c;_all 查询是一种特殊的查询方式&#xff0c;用于在多个索引或数据流中执行搜索操作&#xff0c;而无需显式指定每个目标索引或数据流的名称。以下是关于 _all 查询的详细说明&#xff1a; _all 查询概述 用途&#xff1a;_all 查询允许您在多个…

96,【4】 buuctf web [BJDCTF2020]EzPHP

进入靶场 查看源代码 GFXEIM3YFZYGQ4A 一看就是编码后的 1nD3x.php 访问 得到源代码 <?php // 高亮显示当前 PHP 文件的源代码&#xff0c;用于调试或展示代码结构 highlight_file(__FILE__); // 关闭所有 PHP 错误报告&#xff0c;防止错误信息泄露可能的安全漏洞 erro…

kamailio-ACC、ACC_JSON 和 ACC_RADIUS 的区别

ACC、ACC_JSON 和 ACC_RADIUS 的区别 ACC、ACC_JSON 和 ACC_RADIUS 都是 Kamailio 中用于计费&#xff08;Accounting&#xff09;的模块&#xff0c;但它们的功能和后端支持有所不同。以下是它们的区别及案例说明&#xff1a; 1. ACC 模块 功能&#xff1a;ACC 模块是 Kamai…

C++ Primer 标准库类型string

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

R绘图 | pheatmap 聚类并设置间隔

一个pheatmap的小例子&#xff0c;包含设置列注释&#xff0c;列注释颜色&#xff0c;聚类&#xff0c;聚类间隔&#xff0c;保存为pdf等。 加方框失败&#xff0c;可以后续使用Illustrator手工添加 效果图&#xff1a; library(pheatmap) set.seed(2025) mat <- matrix…

springboot中路径默认配置与重定向/转发所存在的域对象

Spring Boot 是一种简化 Spring 应用开发的框架&#xff0c;它提供了多种默认配置和方便的开发特性。在 Web 开发中&#xff0c;路径配置和请求的重定向/转发是常见操作。本文将详细介绍 Spring Boot 中的路径默认配置&#xff0c;并解释重定向和转发过程中存在的域对象。 一、…