MVC模式和MVVM模式
目录
一、MVC模式和MVVM模式
1. MVC模式
2. MVVM 模式
3.在Qt中的应用示例
4.总结
二、MVC与MVVM模式的共同点和区别
1.共同点
2.区别
3.交互流程
4.总结
MVC(Model-View-Controller)和MVVM(Model-View-ViewModel)是两种常见的软件设计模式,主要用于将用户界面(UI)与业务逻辑和数据分离,以提高代码的可维护性和可扩展性。
一、MVC模式和MVVM模式
1. MVC模式
核心思想:将应用程序分为三个核心组件,职责分离。
-
Model:管理数据和业务逻辑(如数据库操作、数据计算)。
-
View:负责界面显示,不处理业务逻辑。
-
Controller:接收用户输入(如按钮点击),协调 Model 和 View 的交互。
工作流程:
-
用户通过 View 触发事件(如点击按钮)。
-
Controller 接收事件,调用 Model 修改数据。
-
Model 更新数据后,通知 View 刷新界面(通过观察者模式或直接调用)。
- 优点:职责清晰,适合复杂交互的应用。
- 缺点:View 和 Controller 可能耦合较紧,难以独立测试。
2. MVVM 模式
核心思想:通过数据绑定实现 View 和 Model 的自动同步。
-
Model:同 MVC,管理数据。
-
View:负责界面显示,声明式定义 UI(如 QML)。
-
ViewModel:暴露数据属性和命令,作为 View 和 Model 的桥梁,处理业务逻辑。
工作流程:
-
View 通过数据绑定(如 QML 的
property binding
)直接关联 ViewModel 的属性。 -
用户操作 View(如输入文本)自动更新 ViewModel。
-
ViewModel 修改 Model,Model 变化后通过通知机制(如信号)更新 ViewModel,再同步到 View。
- 优点:View 和 ViewModel 解耦,适合数据驱动型 UI。
- 缺点:数据绑定可能增加调试复杂度。
3.在Qt中的应用示例
示例1:Qt 中的MVC(使用QWidgets)
-
场景:文件浏览器(显示文件夹结构)。
-
代码结构:
// Model: QFileSystemModel 提供文件系统数据 QFileSystemModel *model = new QFileSystemModel; model->setRootPath(QDir::homePath());// View: QTreeView 和 QListView 显示数据 QTreeView *treeView = new QTreeView; treeView->setModel(model); QListView *listView = new QListView; listView->setModel(model);// Controller: 自定义逻辑(例如双击文件打开) QObject::connect(treeView, &QTreeView::doubleClicked, [](const QModelIndex &index) {QString path = model->filePath(index);QDesktopServices::openUrl(QUrl::fromLocalFile(path)); });
-
说明:
-
Qt 的
Model/View
框架已内置 MVC 支持,但 Controller 通常由 View 的事件处理(如信号槽)实现。
-
示例2:Qt中的MVVM(使用QML + C++)
-
场景:用户信息表单(输入姓名,实时显示欢迎语)。
-
代码结构:
// View: main.qml TextField {text: viewModel.userName // 绑定 ViewModel 属性onTextChanged: viewModel.setUserName(text) } Text {text: "Hello, " + viewModel.userName // 自动更新 }
// ViewModel: UserViewModel 类(继承 QObject) class UserViewModel : public QObject {Q_OBJECTQ_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged) public:QString userName() const { return m_name; }void setUserName(const QString &name) {if (m_name != name) {m_name = name;emit userNameChanged();// 可选:更新 Model(如保存到数据库)}} signals:void userNameChanged(); private:QString m_name; };// 在 C++ 中暴露 ViewModel 到 QML UserViewModel viewModel; QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("viewModel", &viewModel);
-
说明:
-
QML 的
property binding
实现自动同步,ViewModel 通过Q_PROPERTY
暴露数据。
-
4.总结
-
MVC:适合传统 QWidgets 应用,需手动连接信号槽(Controller 逻辑分散)。
-
MVVM:适合 QML 应用,利用数据绑定简化代码,ViewModel 集中管理状态。
-
Qt 特点:
-
Qt 的
Model/View
框架(如QTableView + QSqlTableModel
)是 MVC 的简化版。 -
MVVM 在 QML 中更自然,因为数据绑定是 QML 的核心特性。
-
二、MVC与MVVM模式的共同点和区别
1.共同点
- 关注点分离
- 均将应用程序分为数据层(Model)、界面层(View)和逻辑层(Controller 或 ViewModel),实现职责解耦。
- 数据与界面分离
- Model 独立管理数据逻辑,不依赖具体界面实现。
- 用户输入处理
- 均需处理用户交互(如点击、输入),并更新数据和界面。
- 同步机制
- 需要确保数据变化后界面及时更新(MVC 通过观察者模式,MVVM 通过数据绑定)。
2.区别
特性 | MVC | MVVM |
---|---|---|
核心组件 | Model、View、Controller | Model、View、ViewModel |
数据流方向 | 单向:用户操作 → Controller → Model → View | 双向:View ↔ ViewModel ↔ Model(自动同步) |
界面更新方式 | 手动更新(需显式调用 View 刷新逻辑) | 自动更新(通过数据绑定) |
适用场景 | 复杂交互控制(如桌面应用) | 数据驱动型 UI(如动态表单、实时仪表盘) |
耦合度 | View 和 Controller 可能耦合较紧 | View 和 ViewModel 完全解耦 |
典型框架 | Qt Widgets、Spring MVC | Qt QML、WPF、Vue.js |
3.交互流程
1. MVC模式交互流程:
-
用户操作触发 View 的事件(如点击按钮)。
-
Controller 接收事件,调用 Model 修改数据。
-
Model 更新后通知 View 刷新界面(通过观察者模式或直接调用)。
2. MVVM交互流程:
-
View 通过数据绑定直接关联 ViewModel 的属性(如 QML 的
text: viewModel.name
)。 -
用户修改 View(如输入文本),自动更新 ViewModel。
-
ViewModel 修改 Model,Model 变化后通过信号通知 ViewModel,触发 View 自动更新。
4.总结
-
选择 MVC:
适合需要精细控制交互逻辑的桌面应用(如复杂表单验证、多窗口管理)。 -
选择 MVVM:
适合数据驱动且界面频繁更新的场景(如实时监控、动态仪表盘)。 -
Qt 的灵活性:
-
在 QWidgets 中,MVC 更常见,但需手动管理数据流。
-
在 QML 中,MVVM 是自然选择,利用其声明式语法和数据绑定特性。
-
相关文章:
MVC模式和MVVM模式
目录 一、MVC模式和MVVM模式 1. MVC模式 2. MVVM 模式 3.在Qt中的应用示例 4.总结 二、MVC与MVVM模式的共同点和区别 1.共同点 2.区别 3.交互流程 4.总结 MVC(Model-View-Controller)和MVVM(Model-View-ViewModel)是两种…...

CSS伪类选择器全解析:让你的样式更加灵活和智能
目录 前言 一、什么是伪类选择器? 二、常见的伪类选择器详解 1. :hover —— 悬停状态 2. :active —— 活动状态 3. :focus —— 焦点状态 综合案例 4. :first-child —— 第一个子元素 5. :last-child —— 最后一个子元素 6. :nth-child(n) —— 按顺序选…...

【GESP】2024年12月图形化一级 -- 飞行的小猫
飞行的小猫 1. 准备工作 (1)删除默认小猫角色。 (2)添加角色Cat Flying和Clouds。 (3)删除默认白色背景,添加背景Blue Sky 2。 2. 功能实现 (1)点击绿旗,…...

30填学习自制操作系统第二天
今天要干什么? 初步了解汇编语言使用汇编重新写个昨天的镜像文件继续开发 一: 什么是电信号? 电脑的处理中心是CPU,即“central process unit”的缩写,翻译成中文就是“中央处理单元”,顾名思义,他就是…...
MapReduce的工作原理及其在大数据处理中的应用
MapReduce是一种由Google提出的面向大数据并行处理的计算模型、框架和平台,它通过将复杂的数据处理任务分解为两个简单的阶段——Map(映射)和Reduce(归约),实现了分布式并行计算,极大地提高了数…...
vue3.x 的provide 与 inject详细解读
在 Vue 3.x 中,provide 和 inject 是一对用于实现依赖注入的 API。它们允许父组件向其所有子组件(无论嵌套多深)传递数据或方法,而不需要通过 props 逐层传递。这在开发复杂组件或高阶组件时非常有用。 1. provide 的基本用法 p…...
c#中“事件-event”的经典示例与理解
在C#编程语言中,事件(Event)是一个非常重要的概念,它提供了一种松耦合的方式,让对象间能够通知彼此,而无需直接联系。事件的使用可以让我们的代码更加灵活、可扩展且易于维护。 事件可以视作委托的实例&…...
《第三代大语言模型Grok 3:闪亮登场》
《第三代大语言模型Grok 3:闪亮登场》 在科技飞速发展的今天,人工智能领域的每一次重大突破都如同巨石投入平静湖面,激起千层浪。当地时间 2 月 15 日,马斯克在社交平台 X 上投下了这样一颗 “巨石”,他宣布旗下人工智能公司 xAI 开发的第三代大语言模型 Grok 3,将于北京…...
rem、em、vw区别
在前端开发里,rem、em、vw都是用来设置元素大小的单位,下面就用大白话讲讲它们的区别。 参考标准不一样 rem:就像大家都用同一把“大尺子”来量东西,这把“大尺子”就是网页里根元素(也就是 <html> 标签&#…...
最新Apache Hudi 1.0.1源码编译详细教程以及常见问题处理
1.最新Apache Hudi 1.0.1源码编译 2.Flink、Spark、Hive集成Hudi 1.0.1 3.flink streaming写入hudi 目录 1. 版本介绍 2. 安装maven 2.1. 下载maven 2.2. 设置环境变量 2.3. 添加Maven镜像 3. 编译hudi 3.1. 下载hudi源码 3.2. 修改hudi源码 3.3. 修改hudi-1.0.1/po…...

C语言简单练习题
文章目录 练习题一、计算n的阶乘bool类型 二、计算1!2!3!...10!三、计算数组arr中的元素个数二分法查找 四、动态打印字符Sleep()ms延时函数system("cls")清屏函数 五、模拟用户登录strcmp()函数 六、猜数字小游戏产生一个随机数randsrandRAND_MAX时间戳time() 示例 …...
C++ ——static关键字
1、static修饰局部变量---->静态局部变量 特点: (1)第一次调用时创建,然后第一次调用结束时没有被回收,以后每次调用,都延用上一次调用结束时的值,直到程序结束时,才被回收 &a…...
Jasper AI技术浅析(二):语言模型
Jasper AI 的核心语言模型是基于 OpenAI 的 GPT-4(Generative Pre-trained Transformer 4)构建的。GPT-4 是一种生成式预训练语言模型,利用深度学习技术,特别是 Transformer 架构,来理解和生成自然语言。 1. GPT-4 的基本原理 1.1 Transformer 架构 GPT-4 基于 Transfo…...

QML 部件获得焦点触发的全局槽函数 onActiveFocusItemChanged
在qml的window窗口中,假如添加里许多其他部件,当这些部件改变时,会有一个全局部件焦点改变槽函数触发,就是 onActiveFocusItemChanged 可以通过此槽函数就可以知道当前焦点在哪一个部件上,也可以做一些自动化测试等&…...

【git】工作场景下的 工作区 <-> 暂存区<-> 本地仓库 命令实战 具体案例
🚀 Git 工作区 → 暂存区 → 本地仓库 → 回退实战 Git 的核心流程是: 👉 工作区(Working Directory) → git add → 暂存区(Staging Area) → git commit → 本地仓库(Local Repos…...
Python 中从零开始的随机梯度下降
文章目录 一、说明二、了解基础知识的重要性:2.1 什么是梯度下降?2.2 梯度下降的类型: 三、随机梯度下降 (SGD) 有何不同3.1 随机性的概念:3.2 SGD的优点和缺点: 四、随机梯度下降的分步说明五、…...
期权隐含波动率是什么意思?
财顺小编本文主要介绍期权隐含波动率是什么意思?期权隐含波动率(Implied Volatility)是根据当前期权市场价格,利用期权定价模型(如Black-Scholes模型)推导出的关于合约标的理论上的价格波动率。它反映了市场…...

python中使用数据库sqlite3
Python使用sqlite3数据库 python3.x标准库内置了SQLite3 查看sqlite的版本 import sqlite3 sqlite_version sqlite3.sqlite_version print(f"SQLite version: {sqlite_version}") 显示 导入模块连接sqlitte3 import sqlite3 consqlite3.connect("d:/fi…...
JavaScript数组-数组的概念
在JavaScript编程中,数组(Array)是一种非常重要的数据结构,它允许我们将多个值存储在一个单独的变量中。数组可以包含任意类型的元素,如数字、字符串、对象甚至是其他数组,并提供了丰富的内置方法来操作这些…...
英语---基础词汇库
〇、动词类(常见谓语表述) 1.show,indicate,find 认为,表明 2.improve,promote,boost,enhance,increase,advocate,strength 改善,提升,促进,增强࿰…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...