MVC,MVP和MVVM架构解析

2023-11-12


关于架构,框架和设计模式三者的说明

  • 架构
    架构是一种代码的管理方案,用来提高代码的可读性和可维护性,MVC,MVP,MVVM,或者自己对自己项目代码的管理方案都可以称为架构
  • 框架
    框架是一种业务处理方案,是帮你写好的东西,已经完成部分业务,继承到自己项目中完成项目中部分功能,像okHttp,Retrofit,Glide等第三方库可以成为框架
  • 设计模式
    设计模式是功能的实现方案,是能达到某种目的的一种代码的写法,以后也会对各种设计模式进行详细的讲解

一、MVC

1.概念

MVC, 即Model-View-Controller, 基于页面逻辑的修改要多于业务逻辑, 分离两种逻辑减少类代码的修改

2.结构

  • Model: 即数据层, 负责处理业务逻辑, 监听网络与数据库接口
  • View: 即界面(UI)层, 显示来源于Model的数据
  • Contoller: 即逻辑层, 传递用户的交互和更新Model的数据
    MVC

3.模式

根据MVC架构, View和Controller都会依赖于Model, View显示Model数据, Controller更新Model数据. Model从项目中分离后, 独立于UI, 允许测试. 更新Model方式的不同, 把MVC架构分为被动(Passive)模式和主动(Active)模式.

  • 被动模式:在被动模式中, Controller是唯一操作Model的类. 基于用户的响应事件, Controller通知Model更新数据. 在Model更新后, Controller通知View更新UI, View从Model中获取数据
    被动模式
  • 主动模式:在主动模式中, Controller不是唯一操作Model的类, Model存在自更新机制. 在更新数据时, Model层使用观察者(Observer)模式通知View和其他类. View实现观察者的接口, 在Model中, 注册成为观察者, 接收通知.
    在这里插入图片描述
    当Model层发生数据更新时, 告知全部观察者. View从Model中更新数据.
    在这里插入图片描述

4.优缺点

  • 优点:MVC模式, 分离类的UI与业务职责, 增加可测试性与可扩展性. Model不引用任何Android类, 允许单元测试(Unit Test). Controller含有View的引用, 不引用Android类, 允许单元测试. View满足单一职责原则(SRP), 传递事件至Controller, 展示Model数据, 不包含业务逻辑, 允许UI测试.
  • 缺点:
    1.View既依赖于Controller又依赖于Model. 在修改UI逻辑时, 也需要修改Model, 降低架构的灵活性. View与Model的职责部分重叠, 过于耦合, 在处理UI逻辑时, 被动模式与主动模式都会产生若干问题.
    2.在被动模式中, Controller通知Model更新数据, 并通知View显示. 对于UI逻辑, 如果View处理, 单元测试会遗漏逻辑; 如果Model处理, 则隐式地依赖于View, 导致模块增加耦合
    3.MVC架构含有致命问题, 即View同时含有Controller与Model的引用; UI逻辑同时存在于View与Model之间. 这些问题导致业务逻辑与UI逻辑无法分离, 增加模块耦合, 影响重构. 这些问题在MVC的进化版MVP中逐步解决.

5.适用场景

项目体量较小,维护频率不高的应用

二、MVP

1.概念

MVP属于MVC的演化版本,目的是让Model和View完全解耦

2.结构

  • View:对应于Activity,负责View的绘制以及与用户交互
  • Model:业务逻辑和实体模型
  • Presenter:负责完成View于Model间的交互

3.与MVC对比

  • MVC下的数据走向
    在这里插入图片描述
  • MVP下的数据走向
    在这里插入图片描述
  • 与MVC的区别对比
    最明显的区别就是,MVC中是允许Model和View进行交互的,而MVP中很明显,Model与View之间的交互由Presenter完成。还有一点就是Presenter与View之间的交互是通过接口的
    在这里插入图片描述

4.优缺点

  • 优点:
    1.降低耦合度
    2.模块职责划分明显
    3.利用测试驱动开发
    4.代码复用
    5.代码灵活度增加
  • 缺点:
    由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么Presenter也需要变更了

5.适用场景

项目如果过于庞大,且需要频繁对于VIEW进行调整或者变更的项目不适用于此模式常规的中小型应用适合于当前业务需求


三、MVVM

1.结构

  • Model:数据层,包含数据实体和对数据实体的操作
  • ViewModel:关联层,将Model和View进行绑定,Model或者View更改时,实时刷新对方。ViewModel只做和业务逻辑相关的工作,不涉及任何和UI相关的操作,不持有控件引用,不更新UI
  • View只做和UI相关的工作,不涉及任何业务逻辑,不涉及操作数据,不处理数据。UI和数据严格的分开

2.解析

在这里插入图片描述

  • View显而易见Activity/Fragment便是MVVM中的View,当收到ViewModel传递过来的数据时,Activity/Fragment负责将数据以你喜欢的方式显示出来。View还包括ViewDataBinding,图中并没有体现。
  • ViewModelViewModel作为Activity/Fragment与其他组件的连接器。负责转换和聚合Model中返回的数据,使这些数据易于展示,并把这些数据改变即时通知给Actvity/Fragment。ViewModel是具有生命周期意识的,当Activity/Fragment销毁时ViewModel的onClear方法会被回调,你可以在这里做一些清理工作。LiveData是具有生命周期意识的一个可观察的数据持有者,ViewModel中的数据有LiveData持有,并且只有当Activity/Fragment处于活动时才会通知UI数据的改变,避免无用的刷新UI。
  • ModelRepository及其下方就是model了。Repository负责提取和处理数据。数据来源可以是本地数据库,也可以来自网络,这些数据统一有Repository处理,对应隐藏数据来源以及获取方式。
  • Binder绑定器Android中的数据绑定技术由DataBinding和LiveData共同实现。当Activity/Fragment接收到来自ViewModel中的新数据时(由LiveData自动通知数据的改变),将这些数据通过DataBinding绑定到ViewDataBinding中,UI将会自动刷新。

3.MVVM架构本质

1.解耦,区别于MVC不会产生巨量代码,区别于MVP不会产生大量接口
2.职责更加明确,在mvp模式中,p需要持有V的引用,才能去刷新UI,在MVVM模式中,View和Model使用databingding进行双向绑定,一方改变会直接通知另外一方,使得viewModel能专注于业务逻辑的处理,而不需要去关心UI刷新

4.DataBinding和MVVM关系

MVVM是一种架构模式,DataBinding是一个实现数据和UI绑定的框架,是实现MVVM模式的工具

5.优缺点

  • 优点:
    1.使得M,V,VM的解耦更加彻底,在mvp模式中,p需要持有V的引用,才能去刷新UI,在MVVM模式中,View和Model使用databingding进行双向绑定,一方改变会直接通知另外一方,使得viewModel能专注于业务逻辑的处理,而不需要去关心UI刷新
    2.不会像MVC一样导致Activity中代码量巨大,也不会像MVP一样出现大量的View接口(Presente与View是通过接口进行交互的)。项目结构更加低耦合。

  • 缺点:
    1.数据绑定使得Bug很难被调试
    2.一个大的模块中,model也会很大,虽然使用方便了也很容易保证了数据的一致性,但是长期持有,不释放内存,就造成了花费更多的内存
    3.数据双向绑定不利于代码重用。客户端开发最常用的重用时View,但是数据双向绑定技术,让你在一个View都绑定了一个model,不同模块的model都不同,那就不能简单重用View了

6.适用场景

业务处理逻辑大多数在后端的情况下前端只要做展示而不需要做大量的业务处理的项目

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MVC,MVP和MVVM架构解析 的相关文章

  • Android 版 Robotium - solo.searchText () 不起作用

    我在使用 Robotium 时遇到 searchText 函数问题 我正在寻找这个字符串
  • Flutter 深度链接

    据Flutter官方介绍深层链接页面 https flutter dev docs development ui navigation deep linking 我们不需要任何插件或本机 Android iOS 代码来处理深层链接 但它并没
  • Android 启动器快捷方式

    我制作了一个简单的打卡 打卡时钟应用程序 我想向用户添加在主屏幕上创建快捷方式的选项 该快捷方式将切换应用程序的状态 超时 超时 但我根本不希望此快捷方式在屏幕上打开应用程序 这是我的 setupShortcut private void
  • 检查 Android 手机上的方向

    如何查看Android手机是横屏还是竖屏 当前配置用于确定要检索的资源 可从资源中获取Configuration object getResources getConfiguration orientation 您可以通过查看其值来检查方向
  • Spring Data 与 Spring Data JPA 与 JdbcTemplate

    我有信心Spring Data and Spring Data JPA指的是相同的 但后来我在 youtube 上观看了一个关于他正在使用JdbcTemplate在那篇教程中 所以我在那里感到困惑 我想澄清一下两者之间有什么区别Spring
  • 反思 Groovy 脚本中声明的函数

    有没有一种方法可以获取 Groovy 脚本中声明的函数的反射数据 该脚本已通过GroovyShell目的 具体来说 我想枚举脚本中的函数并访问附加到它们的注释 Put this到 Groovy 脚本的最后一行 它将作为脚本的返回值 a la
  • 归并排序中的递归:两次递归调用

    private void mergesort int low int high line 1 if low lt high line 2 int middle low high 2 line 3 mergesort low middle l
  • 检查 protobuf 消息 - 如何按名称获取字段值?

    我似乎无法找到一种方法来验证 protobuf 消息中字段的值 而无需显式调用其 getter 我看到周围的例子使用Descriptors FieldDescriptor实例到达消息映射内部 但它们要么基于迭代器 要么由字段号驱动 一旦我有
  • org.jdesktop.application 包不存在

    几天以来我一直在构建一个 Java 桌面应用程序 一切都很顺利 但是今天 当我打开Netbeans并编译文件时 出现以下编译错误 Compiling 9 source files to C Documents and Settings Ad
  • 通过 ADB 拔出设备:“找不到服务”

    我必须测试我的应用程序在打瞌睡模式下的行为 根据文档 https developer android com training monitoring device state doze standby html testing doze 我
  • 下载后从谷歌照片库检索图像

    我正在发起从图库中获取照片的意图 当我在图库中使用 Nexus 谷歌照片应用程序时 一切正常 但如果图像不在手机上 在 Google Photos 在线服务上 它会为我下载 选择图像后 我将图像发送到另一个活动进行裁剪 但在下载的情况下 发
  • 当手机旋转(方向改变)时如何最好地重新创建标记/折线

    背景 开发一个使用 Android Google Map v2 的本机 Android 应用程序 使用android support v4 app FragmentActivity 在 Android v2 2 上运行 客观的 在更改手机方
  • 运行 Jar 文件时出现问题

    我已将 java 项目编译成 Jar 文件 但运行它时遇到问题 当我跑步时 java jar myJar jar 我收到以下错误 Could not find the main class myClass 类文件不在 jar 的根目录中 因
  • 使用 Espresso 检查 EditText 的字体大小、高度和宽度

    如何使用 Espresso 检查 EditText 的字体大小 高度和宽度 目前要分割我使用的文本 onView withId R id editText1 perform clearText typeText Amr 并阅读文本 onVi
  • 查看Jasper报告执行的SQL

    运行 Jasper 报表 其中 SQL 嵌入到报表文件 jrxml 中 时 是否可以看到执行的 SQL 理想情况下 我还想查看替换每个 P 占位符的值 Cheers Don JasperReports 使用 Jakarta Commons
  • 休眠以持久保存日期

    有没有办法告诉 Hibernate java util Date 应该持久保存 我需要这个来解决 MySQL 中缺少的毫秒分辨率问题 您能想到这种方法有什么缺点吗 您可以自己创建字段long 或者使用自定义的UserType 实施后User
  • com.jcraft.jsch.JSchException:身份验证失败

    当我从本地磁盘上传文件到远程服务器时 出现这样的异常 com jcraft jsch JSchException Auth fail at org apache tools ant taskdefs optional ssh Scp exe
  • JAVA - 如何从扫描仪读取文件中检测到“\n”字符

    第一次海报 我在读取文本文件的扫描仪中读取返回字符时遇到问题 正在读取的文本文件如下所示 test txt start 2 0 30 30 1 1 90 30 0 test txt end 第一行 2 表示两个点 第二行 位置索引 0 xp
  • java8 Collectors.toMap() 限制?

    我正在尝试使用java8Collectors toMap on a Stream of ZipEntry 这可能不是最好的想法 因为在处理过程中可能会发生异常 但我想这应该是可能的 我现在收到一个我不明白的编译错误 我猜是类型推理引擎 这是
  • Jackson 将单个项目反序列化到列表中

    我正在尝试使用一项服务 该服务为我提供了一个带有数组字段的实体 id 23233 items name item 1 name item 2 但是 当数组包含单个项目时 将返回该项目本身 而不是包含一个元素的数组 id 43567 item

随机推荐

  • conda upgrade --all惹的祸,该怎么解决?

    本想要安装scikit surprise库 由于环境问题 就更新一下 谁知道差点酿成大祸 anaconda不灵了 无论什么语句都报错 jupyter notebook 不能用 navigator也打不开 万念俱灰了 导致我想要重装anaco
  • atx860和java_捷安特XTC800和ATX860有什么区别

    展开全部 区别比较大 简单说 ATX 8xx就是e69da5e887aa62616964757a686964616f31333431353237ATX 6xx的 局部升级 轮组由26寸换为27 5寸 车架外观改进 变速套件等级略微提高 仅此
  • mmclassification 训练自定义数据

    1 mmclassification 安装 如果环境已安装mmclassification 请跳过该步骤 mmclassification框架安装与调试验证请参考博客 mmclassification安装与调试 Coding的叶子的博客 C
  • STM32基于IIC协议的温湿度(AHT20)采集

    STM32基于IIC协议的温湿度 AHT20 采集 文章目录 STM32基于IIC协议的温湿度 AHT20 采集 1 IIC总线协议 1 1 什么是IIC协议 1 2 IIC协议的物理层和协议层 1 2 1 物理层 1 2 2 协议层 1
  • orm模型的查询方法集合

    目录 3 4 1 基本查询 3 4 2过滤查询 3 4 2 2 模糊查询 3 4 2 3 空查询 3 4 2 4 范围查询 3 4 2 5 比较查询 3 4 2 6 日期查询 3 4 3 1 F对象 3 4 3 2 Q对象 values 返
  • Aborted (core dumped) Assertion `Engine.getNbBindings() == 4' failed.

    记录一次特别粗心的错误 错误代码位置 assert的作用是现计算表达式 expression 如果其值为假 即为0 那么它先向stderr打印一条出错信息 然后通过调用 abort 来终止程序运行 需要 inputname 3 output
  • 垂直广告是什么意思_网上常看到带货这个词,那么带货到底是什么意思?又要怎么通过平台带货呢?...

    网上常看到带货这个词 那么带货到底是什么意思 又要怎么通过平台带货呢 直播带货就是通过短视频平台 吸引消费者来购买自己所售卖的产品 可以投放广告或是与达人合作进行带货 短视频 品牌营销优势 新一代广告宠儿 5G时代即将来临 人们越来越习惯且
  • HTML5----FormData实例用法

    ajax 异步上传文件 1 前言 在网页与后台的交互中 用的最多的网络交互方式之一就是ajax ajax 是免刷新页面就能从进行post与get方式的提交表单和获取服务端数据 但是在原先的ajax中 是不能携带文件上传的 但是由于h5里面的
  • Mysql数据库手册

    数据库基本概念 1 数据库 就是数据的仓库 由表 关系 操作对象组成 2 表 由行和列组成 数据都存放在表中 由于mysql是关系数据库 所以表又被称为关系 3 字段 就是属性 4 记录 一行数据就是一条记录 也是一条实体 需要设置主键 5
  • 基于惯性动作捕捉技术进行快速动画制作教程

    长久以来动画制作流程上有着诸多不可回避的问题 尤其在于角色动画的制作周期和动画效果方面 一般来说 每一秒钟的角色动画都需要动画师手动关键帧制作耗费8小时才能完成 也就是说 一个动画师每个月只能制作出22秒动画 动作捕捉技术为动画制作者带来福
  • Elasticsearch-基本命令

    基本命令 创建索引 添加数据 删除数据 简单查询 复杂查询1 复杂查询2 获得所有index 获得所有mapping type 根据某个字段精确查找 api的分组查询 bool查询 创建索引 put http localhost 9200
  • LSTM生成文本(字符级别)

    20200817 引言 在网上看到过一些利用深度学习来生成文本的文章 不管生成宋词也好 生成小说也好 各种各样 都是利用深度学习的模型来生成新的东西 之前的时候 我也一直觉得 他们这种生成方式 应该就是记忆性的东西 他并没有真正的从语义的角
  • jdbc导出mysql数据库_原生JDBC方式导出MySQL数据库

    现在的应用系统越来越多的都是业务系统与数据库系统是分离的 这里就会涉及到数据库备份的问题 如果业务系统与数据库是在同一服务器 可以很简单的用mysql自带的命令 mysqldump databases dbName gt dbNameBak
  • stm32 mqtt 如何判断心跳包发送成功_Dubbo 现有心跳方案总结以及改进建议

    1 前言 设计一个好的心跳机制并不是一件容易的事 就我所熟知的几个 RPC 框架 它们的心跳机制可以说大相径庭 这篇文章我将探讨一下如何设计一个优雅的心跳机制 主要从 Dubbo 的现有方案以及一个改进方案来做分析 2 预备知识 因为后续我
  • linux的inode暴增

    author skate time 2012 04 26 linux的inode暴增 今天刚到公司 接收到一个报警短信 一个数据库的inode使用率达到99 root DBtmp df h Filesystem Size Used Avai
  • 我 JS 写的好好的,为什么要用那么复杂的 TS

    今年前端面试有个很有意思的现象 最经典的 JavaScript 基础类面试题 不在被面试官宠幸 原因很简单 现在市场经济收紧 公司的项目决策中往往切割掉了边角试错成本 而 TypeScript 无疑更适合构建大项目和管理 就像 Java 和
  • 彻底理解embedding

    本文转载自https blog csdn net weixin 42078618 article details 84553940 版权问题请联系博主删除 首先 我们有一个one hot编码的概念 假设 我们中文 一共只有10个字 只是假设
  • 毕业设计记录-Pytorch学习-自己手写数字识别

    今天用之前的模型训练手写数字数据集 训练了50轮 效果如下 然后我就准备用自己手写的数字来检验看看 模型的准确率 自己找的一些数字图片 但是经过测试全部预测成3 很不解 搞了好几个小时 到最后无意间看到他的数据集的时候才知道哪出了问题 这是
  • Linux网络服务部署yum仓库

    目录 1 Yum概述 2 Yum实现过程 3 Yum配置文件 3 1yum主配置文件 etc yum conf 3 2仓库设置文件 etc yum repos d repo 4 yum命令详解 5 源地址 6 搭建仓库的方式 6 1搭建本地
  • MVC,MVP和MVVM架构解析

    文章目录 关于架构 框架和设计模式三者的说明 一 MVC 1 概念 2 结构 3 模式 4 优缺点 5 适用场景 二 MVP 1 概念 2 结构 3 与MVC对比 4 优缺点 5 适用场景 三 MVVM 1 结构 2 解析 3 MVVM架构