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_Htypedef 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_Htypedef 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_Htypedef 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_Htypedef 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协助下
相关文章:

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

基于RTOS的STM32游戏机
1.游戏机的主要功能 所有游戏都来着B站JL单片机博主开源 这款游戏机具备存档与继续游戏功能,允许玩家在任何时候退出当前游戏并保存进度,以便日后随时并继续之前的冒险。不仅如此,游戏机还支持多任务处理,玩家可以在退出当前游戏…...

【CPP】CPP经典面试题
文章目录 引言1. C 基础1.1 C 中的 const 关键字1.2 C 中的 static 关键字 2. 内存管理2.1 C 中的 new 和 delete2.2 内存泄漏 3. 面向对象编程3.1 继承和多态3.2 多重继承 4. 模板和泛型编程4.1 函数模板4.2 类模板 5. STL 和标准库5.1 容器5.2 迭代器 6. 高级特性6.1 移动语义…...

WPF基础03——InitializeComponent()函数解释
总述 InitializeComponent(),是MainWindow中的构造函数,实际写项目过程中,多多少少都会碰到该函数报错的情况,现在对InitializeComponent()做一些理解和说明。 在 WPF 中,XAML 文件和代码后台…...
如何在自己mac电脑上私有化部署deep seek
在 Mac 电脑上私有化部署 DeepSeek 的步骤如下: 1. 环境准备 安装 Homebrew(如果尚未安装): Homebrew 是 macOS 上的包管理工具,用于安装依赖。 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com…...
iOS 老项目适配 #Preview 预览功能
前言 iOS 开发者 最憋屈的就是UI 布局慢,一直以来没有实时预览功能,虽然swiftUI 早就支持了,但是目前主流还是使用UIKit在布局,iOS 17 苹果推出了 #Preview 可以支持UIKit 实时预览,但是仅仅是 iOS 17,老项目怎么办呢?于是就有了这篇 老项目适配 #Preview 预览 的文章,…...
7 与mint库对象互转宏(macros.rs)
macros.rs代码定义了一个Rust宏mint_vec,它用于在启用mint特性时,为特定的向量类型实现与mint库中对应类型的相互转换。mint库是一个提供基本数学类型(如点、向量、矩阵等)的Rust库,旨在与多个图形和数学库兼容。这个宏…...
pytorch实现变分自编码器
人工智能例子汇总:AI常见的算法和例子-CSDN博客 变分自编码器(Variational Autoencoder, VAE)是一种生成模型,属于深度学习中的无监督学习方法。它通过学习输入数据的潜在分布(Latent Distribution)&…...

Node.js与嵌入式开发:打破界限的创新结合
文章目录 一、Node.js的本质与核心优势1.1 什么是Node.js?1.2 嵌入式开发的范式转变二、Node.js与嵌入式结合的四大技术路径2.1 硬件交互层2.2 物联网协议栈2.3 边缘计算架构2.4 轻量化运行时方案三、实战案例:智能农业监测系统3.1 硬件配置3.2 软件架构3.3 核心代码片段四、…...
Noise Conditional Score Network
NCSN p σ ( x ~ ∣ x ) : N ( x ~ ; x , σ 2 I ) p_\sigma(\tilde{\mathrm{x}}|\mathrm{x}) : \mathcal{N}(\tilde{\mathrm{x}}; \mathrm{x}, \sigma^2\mathbf{I}) pσ(x~∣x):N(x~;x,σ2I) p σ ( x ~ ) : ∫ p d a t a ( x ) p σ ( x ~ ∣ x ) d x p_\sigma(\mathrm…...

低代码系统-产品架构案例介绍、蓝凌(十三)
蓝凌低代码系统,依旧是从下到上,从左至右的顺序。 技术平台h/iPaas 指低层使用了哪些技术,例如:微服务架构,MySql数据库。个人认为,如果是市场的主流,就没必要赘述了。 新一代门户 门户设计器&a…...

51单片机 02 独立按键
一、独立按键控制LED亮灭 轻触按键:相当于是一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通和断开。 #include <STC89C5xRC.H> void main() { // P20xFE;while(1){…...

2021.3.1的android studio版本就很好用
使用最新版的studio有个问题就是gradle版本也比较高,这样就容易出现之前项目不兼容问题,配置gradle可能会出现很多问题比较烦,所以干脆就用老版本的studio...

CSV数据分析智能工具(基于OpenAI API和streamlit)
utils.py: from langchain_openai import ChatOpenAI from langchain_experimental.agents.agent_toolkits import create_csv_agent import jsonPROMPT_TEMPLATE """你是一位数据分析助手,你的回应内容取决于用户的请求内容。1. 对于文…...
移除元素-双指针(下标)
题目 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:…...
蓝桥杯备赛题目练习(一)
目录 一. 口算练习题 代码如下 代码解读(简略重点): 代码解读(详细): 二. 小乐乐改数字 代码(1):当做整数读取 代码(2):当做字符…...
FortiOS 存在身份验证绕过导致命令执行漏洞(CVE-2024-55591)
免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…...

【多线程】线程池核心数到底如何配置?
🥰🥰🥰来都来了,不妨点个关注叭! 👉博客主页:欢迎各位大佬!👈 文章目录 1. 前置回顾2. 动态线程池2.1 JMX 的介绍2.1.1 MBeans 介绍 2.2 使用 JMX jconsole 实现动态修改线程池2.2.…...
Windows图形界面(GUI)-QT-C/C++ - Qt Combo Box
公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 一、概述 1.1 基本概念 1.2 应用场景对比 二、核心属性详解 2.1 行为控制 2.2 显示配置 三、数据操作与访问 3.1 基础数据管理 3.2 高级数据访问 四、用户交互处理 4.1 信号处…...

开源AI智能名片2 + 1链动模式S2B2C商城小程序:内容价值创造与传播新引擎
摘要:本文聚焦于信息爆炸时代下,内容价值的创造与传播。随着用户角色的转变,其在内容生产与传播中的价值日益凸显。同时,深入探讨开源AI智能名片2 1链动模式S2B2C商城小程序这一创新商业模式,如何借助用户创造内容并传…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...