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

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 的交互。

工作流程

  1. 用户通过 View 触发事件(如点击按钮)。

  2. Controller 接收事件,调用 Model 修改数据。

  3. Model 更新数据后,通知 View 刷新界面(通过观察者模式或直接调用)。

  • 优点:职责清晰,适合复杂交互的应用。
  • 缺点:View 和 Controller 可能耦合较紧,难以独立测试。

2. MVVM 模式

核心思想:通过数据绑定实现 View 和 Model 的自动同步。

  • Model:同 MVC,管理数据。

  • View:负责界面显示,声明式定义 UI(如 QML)。

  • ViewModel:暴露数据属性和命令,作为 View 和 Model 的桥梁,处理业务逻辑。

工作流程

  1. View 通过数据绑定(如 QML 的 property binding)直接关联 ViewModel 的属性。

  2. 用户操作 View(如输入文本)自动更新 ViewModel。

  3. 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.共同点

  1. 关注点分离
  • 均将应用程序分为数据层(Model)、界面层(View)和逻辑层(Controller 或 ViewModel),实现职责解耦。
  1. 数据与界面分离
  • Model 独立管理数据逻辑,不依赖具体界面实现。
  1. 用户输入处理
  • 均需处理用户交互(如点击、输入),并更新数据和界面。
  1. 同步机制
  • 需要确保数据变化后界面及时更新(MVC 通过观察者模式,MVVM 通过数据绑定)。

2.区别

特性MVCMVVM
核心组件Model、View、ControllerModel、View、ViewModel
数据流方向单向:用户操作 → Controller → Model → View双向:View ↔ ViewModel ↔ Model(自动同步)
界面更新方式手动更新(需显式调用 View 刷新逻辑)自动更新(通过数据绑定)
适用场景复杂交互控制(如桌面应用)数据驱动型 UI(如动态表单、实时仪表盘)
耦合度View 和 Controller 可能耦合较紧View 和 ViewModel 完全解耦
典型框架Qt Widgets、Spring MVCQt QML、WPF、Vue.js

3.交互流程

1. MVC模式交互流程

  1. 用户操作触发 View 的事件(如点击按钮)。

  2. Controller 接收事件,调用 Model 修改数据。

  3. Model 更新后通知 View 刷新界面(通过观察者模式或直接调用)。


2. MVVM交互流程

  1. View 通过数据绑定直接关联 ViewModel 的属性(如 QML 的 text: viewModel.name)。

  2. 用户修改 View(如输入文本),自动更新 ViewModel。

  3. 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)点击绿旗&#xff0c…...

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区别

在前端开发里&#xff0c;rem、em、vw都是用来设置元素大小的单位&#xff0c;下面就用大白话讲讲它们的区别。 参考标准不一样 rem&#xff1a;就像大家都用同一把“大尺子”来量东西&#xff0c;这把“大尺子”就是网页里根元素&#xff08;也就是 <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修饰局部变量---->静态局部变量 特点&#xff1a; &#xff08;1&#xff09;第一次调用时创建&#xff0c;然后第一次调用结束时没有被回收&#xff0c;以后每次调用&#xff0c;都延用上一次调用结束时的值&#xff0c;直到程序结束时&#xff0c;才被回收 &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窗口中&#xff0c;假如添加里许多其他部件&#xff0c;当这些部件改变时&#xff0c;会有一个全局部件焦点改变槽函数触发&#xff0c;就是 onActiveFocusItemChanged 可以通过此槽函数就可以知道当前焦点在哪一个部件上&#xff0c;也可以做一些自动化测试等&…...

【git】工作场景下的 工作区 <-> 暂存区<-> 本地仓库 命令实战 具体案例

&#x1f680; Git 工作区 → 暂存区 → 本地仓库 → 回退实战 Git 的核心流程是&#xff1a; &#x1f449; 工作区&#xff08;Working Directory&#xff09; → git add → 暂存区&#xff08;Staging Area&#xff09; → git commit → 本地仓库&#xff08;Local Repos…...

Python 中从零开始的随机梯度下降

文章目录 一、说明二、了解基础知识的重要性&#xff1a;2.1 什么是梯度下降&#xff1f;2.2 梯度下降的类型&#xff1a; 三、随机梯度下降 &#xff08;SGD&#xff09; 有何不同3.1 随机性的概念&#xff1a;3.2 SGD的优点和缺点&#xff1a; 四、随机梯度下降的分步说明五、…...

期权隐含波动率是什么意思?

财顺小编本文主要介绍期权隐含波动率是什么意思&#xff1f;期权隐含波动率&#xff08;Implied Volatility&#xff09;是根据当前期权市场价格&#xff0c;利用期权定价模型&#xff08;如Black-Scholes模型&#xff09;推导出的关于合约标的理论上的价格波动率。它反映了市场…...

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编程中&#xff0c;数组&#xff08;Array&#xff09;是一种非常重要的数据结构&#xff0c;它允许我们将多个值存储在一个单独的变量中。数组可以包含任意类型的元素&#xff0c;如数字、字符串、对象甚至是其他数组&#xff0c;并提供了丰富的内置方法来操作这些…...

英语---基础词汇库

〇、动词类&#xff08;常见谓语表述&#xff09; 1.show&#xff0c;indicate&#xff0c;find 认为&#xff0c;表明 2.improve,promote,boost,enhance,increase&#xff0c;advocate&#xff0c;strength 改善&#xff0c;提升&#xff0c;促进&#xff0c;增强&#xff0…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

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

大话软工笔记—需求分析概述

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

前端导出带有合并单元格的列表

// 导出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&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...