设计模式MVC、MVP、MVVM

news2024/9/22 23:28:07

MVC、MVP和MVVM是什么?

  • MVC:Model-View-Controller,是一种分层解偶的框架,Model层提供本地数据和网络请求,View层处理视图,Controller处理逻辑,存在问题是Controller层和View层的划分不明显,Model层和View层的存在耦合。
  • MVP:Model-View-Presenter,是对MVC的升级,Model层和View层与MVC的意思一致,但Model层和View层不再存在耦合,而是通过Presenter层这个桥梁进行交流。
  • MVVM:Model-View-ViewModel,不同于上面的两个框架,ViewModel持有数据状态,当数据状态改变的时候,会自动通知View层进行更新。

MVC

1.什么是MVC?

1). 软件工程中的一种软件架构, 全称为"Mode–View–Controller", 即为"模型–视图–控制器"

2). MVC将交互式的应用程序分为3个组件:

  • Mode(模型) : 模型层, 包括实体模型与业务模型, 主要作用是完成业务逻辑处理和数据封装。在Android中, 对应实体类/业务类/DAO类
  • View(视图) : 显示层(表示层), 向用户显示信息。在Android中, 对应布局和自定义控件类
  • Controller(控制器) : 控制层, 处理用户输入, 并实现View层与Mode层的协同处理。Android中, 对应Activity

缺点:存在问题是Controller层和View层的划分不明显,Model层和View层的存在耦合。

2.理解MVC

1.基本结构图
在这里插入图片描述
2.Android中的MVC结构:

  • M模型层:
    com.mvc.bean: 实体类包
    com.mvc.utils: 工具包(简单的业务逻辑处理)
    com.mvc.dao: 数据库操作
    com.mvc.net: 网络请求

  • V视图层:
    res下的layout, drawable, values等
    自定义View类等

  • C控制层:
    Activity
    其它应用组件等

3.使用MVC模式的好处 /如果不用MVC会有什么问题?

1). 如果不用View层(布局)?
问题: 每个Activity都需要创建整个布局视图对象, 一个是代码量更大,
另一个不易实现复用(布局是可以轻松实现复用的), 还有就是修改更麻烦
2). 如果不用Mode层(实体Mode)?
问题: 当应用一个界面需要展示或处理很多数据时, 对应的实体类是必不可少的
3). 如果不用Mode层(非实体Mode)?
问题: 那需要将所有的逻辑处理的代码都写到Activity中, 一个使Activity变得太臃肿,
另一个无法复用业务逻辑功能代码

MVC优点:

  • 耦合性低,视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码。
  • 重用性高
  • 生命周期成本低
  • MVC使开发和维护用户接口的技术含量降低
  • 可维护性高,分离视图层和业务逻辑层也使得WEB应用更易于维护和修改
  • 部署快。

MVC缺点:

  • 存在问题是Controller层和View层的划分不明显,Model层和View层的存在耦合。
    不适合小型,中等规模的应用程序,花费大量时间将MVC应用到规模并不是很大的应用程序通常会得不偿失。
    视图与控制器间过于紧密连接,视图与控制器是相互分离,但却是联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。
    视图对模型数据的低效率访问,依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。

MVP

来源

是MVC进一步演化出来的,由Microsoft的Martin Fowler提出。
这个模式被普遍的引用于ASP.NET Web Forms 应用程序。并且也应用于windows form。

1 什么是MVP ?

  • Model层代表了描述业务逻辑和数据的一系列类的集合。它也定义了数据修改和操作的业务规则。
  • View代表了UI组件,像CSS,JQuery,html等。他只负责展示从Presenter接收到的数据。也就是把模型(译者注:非Modle层模型)转化成UI。
  • Presenter负责处理View背后所有的UI事件。它通过View接收用户输入,之后利用Model来处理用户的数据,最后把结果返回给View。与View和Controller不同,View和Presenter之间是完全解耦的,他们通过接口来交互。另外,presenter不像controller处理进入的请求。

2. 理解

1.结构图
在这里插入图片描述

Model层和View层之间不能有交互,要通过Presenter层进行交互,其中View层和Presenter层是通过接口进行交互,可以定义Contract(契约)接口来指定View层和Presenter之间的契约

  • 注意 三层之间调用顺序为view->presenter->model,为了调用安全着想不可反向调用!不可跨级调用!

3.MVP特点

M、V、P之间双向通信。
View 与 Model 不通信,都通过 Presenter 传递。Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。
View 非常薄,不部署任何业务逻辑,称为”被动视图”(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。
Presenter与具体的View是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View时候可以保持Presenter的不变,这样就可以重用。不仅如此,还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试–从而不需要使用自动化的测试工具。

缺点:内存泄露
在MVP模式中,内存泄漏的主要原因是由于当前View层(如Activity或者Fragment)在卸载时,Model层中仍有业务没有结束(如子线程未完成、网络请求超时等),而这里的Presenter层中拥有Mode层和View层的引用,所以Presenter层也暂时无法释放,最终导致View的引用也没有释放,我们的Activity或者Fragment就算时销毁了,GC也无法回收它们,因为还有引用在指向它们呢。

注意:
在MVP中,View层不会部署任何的业务逻辑,从而比较薄,它被称为被动视图(Passive View),意思是它没有任何的主动性,而且这样的设计也方便做单元测试,但是也会有如下问题:

  1. 尽管减少了View层的代码,但是随着业务的复杂度不断提高,Presenter层的代码也会变得越来越臃肿。
  2. View层和Presenter层是通过接口交互的,随着业务的复杂度不断提高,接口数量会大量增加。
  3. 如果View层更新的话,就像UI的输入和数据的变化,都需要主动去调用Presenter层的代码,缺乏自动性和监听性。
  4. MVP是以UI和事件为驱动的传统模型,更新UI需要保证能持有控件的引用,而且更新UI需要考虑Activity或者Fragment的生命周期,防止内存泄漏。

在这里插入图片描述
上图中说明了低层的不会直接给上一层做反馈,而是通过 View 、 Callback 为上级做出了反馈,这样就解决了请求数据与更新界面的异步操作。上图中 View 和 Callback 都是以接口的形式存在的

MVVM

MVVM即Model-View-View Model。这个模式提供对View和View Model的双向数据绑定。这使得View Model的状态改变可以自动传递给View。典型的情况是,View Model通过使用obsever模式(观察者模式)来将View Model的变化通知给model。

MVVM(Model-View-ViewModel)是MVP进一步演化出来的,它也是由Microsoft的Martin Fowler提出
这个模式被广泛应用于WPF,Silverlight,Caliburn,nRoute 等。

1.什么是MVVM?

01.Model:代表了描述业务逻辑和数据的一系列类的集合。它也定义了数据修改和操作的业务规则。
02.View:代表了UI组件,像CSS,JQuery,html等。他只负责展示从Presenter接收到的数据。也就是把模型转化成UI。
03.View Model:负责暴漏方法,命令,其他属性来操作VIew的状态,组装model作为View动作的结果,并且触发view自己的事件。

MVVM模式关键点:

  1. 用户和View交互。
  2. View和ViewModel是多对一关系。意味着一个ViewModel只映射多个View。
  3. View持有ViewModel的引用,但是ViewModel没有任何View的信息。
  4. View 和ViewModel之间有双向数据绑定关系。

2.理解

1.结构图
在这里插入图片描述

  • Model(数据层):负责处理数据逻辑。
  • View(视图层):负责处理视图显示,在Android中使用xml或者Java/Kotlin代码去实现视图,Activity和Fragment承担了此层的责任。
  • ViewModel:负责连接Model层和View层,是这两层的中间纽带,负责处理业务逻辑,View层和ViewModel层是双向绑定的,View层的变动会自动反映在ViewModel层,ViewModel层的变动也会自动反映在View层。

使用MVVM后,每一层的职责也更加清晰了,也方便做单元测试,同时因为View层和ViewModel层是双向绑定,开发者不需要再去主动处理部分逻辑了,减少了不少胶水代码,如果使用了一些数据绑定的库,例如在Android中的DataBinding,可以减少更加多的胶水代码。

MVC和MVP的区别是什么?

MVP是MVC的进一步解耦,简单来讲,在MVC中,View层既可以和Controller层交互,又可以和Model层交互;而在MVP中,View层只能和Presenter层交互,Model层也只能和Presenter层交互,减少了View层和Model层的耦合,更容易定位错误的来源。

MVVM和MVP的最大区别在哪?

MVP中的每个方法都需要你去主动调用,它其实是被动的,而MVVM中有数据驱动这个概念,当你的持有的数据状态发生变更的时候,你的View你可以监听到这个变化,从而主动去更新,这其实是主动的。

ViewModel如何知道View层的生命周期?

事实上,如果你仅仅使用ViewModel,它是感知不了生命周期,它需要结合LiveData去感知生命周期,如果仅仅使用DataBinding去实现MVVM,它对数据源使用了弱引用,所以一定程度上可以避免内存泄漏的发生。

链接

浅谈 MVP in Android
如何更高效的使用MVP以及官方MVP架构解析
Android MVP架构搭建
Android简单实用的MVP框架
Android MVP模式 入门
一步一步带你认识 MVP+Retrofit+Rxjava 并封装(一)
一步一步带你认识 MVP+Retrofit+Rxjava 并封装(二)
Android架构设计–MVP模式第(二)篇,如何减少类爆炸
Android 中的 MVP 模式(带实例)
Android MVP架构的自述
优化你的代码结构 — MVP
灵活利用泛型的MVP模式T-MVP(附带一个快速创建MVP接口的Android Studio插件-TMVPHelper)
高级MVP架构封装演变全过程
Android 滑动选择控件 & MVP+Retrofit+RxJava资源推荐
Android MVP && MVVM深度解析
巧用MVVM搭建GitHub客户端
正确认识 MVC/MVP/MVVM
关于MVC/MVP/MVVM的一些错误认识
MVC、MVP、MVVM,谈谈我对Android应用架构的理解
从google todo-mvp示例再次学习MVP
MVVM,RxJava和Retrofit的一次实践
MVVM设计模式之Data Binding库的使用
Android开发之MVVM新姿势探索
分享一个我开发的MVVM架构的开源小项目
MVVMLin一个基于Jatpack+Kotlin+协程+Retrofit的快速开发框架
犹豫要不要用DataBinding?这篇文章帮你解惑
一款高仿 Eyepetizer | 开眼短视频的 MVVM 开源项目
关于 Android MVVM 一些理解与实践
Android 架构探索,MVVM 原来如此简单!
MVVM+组件化+Arouter实现
Android Kotlin+Jetpack+MVVM
Kotlin协程与JetPack组件初探
Jetpack MVVM七宗罪 之一 :还在使用 Fragment 作为 LifecycleOwner ?
爱了爱了!我理解的Android中MVVM架构模式!
MVVM中LiveData与Flow最佳实践!
彻底理解Android架构,重构Jetpack MVVM!
浅谈Android开发中的MVVM模式
MVVM 进阶版:MVI 架构了解一下
浅尝MVI
MVI 架构封装:快速优雅地实现网络请求
在两个商业App中使用MVI后,我…
项目 todo-mvp
项目MVPArms

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/510995.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot+@Validate+全局异常拦截实现自定义规则参数校验(校验get请求参数不能为空且在指定枚举类型中)

场景 SpringBootValidated实现参数验证(非空、类型、范围、格式等)-若依前后端导入Excel数据并校验为例: SpringBootValidated实现参数验证(非空、类型、范围、格式等)-若依前后端导入Excel数据并校验为例_validated 怎么设置boolean类型非空_霸道流氓气质的博客-…

Elasticsearch02

目录 Elasticsearch02DSL查询文档查询所有全文检索查询精确查询地理查询复合查询 搜索结果处理排序分页高亮 DSL总结RestClient查询文档快速入门:match_all查询match查询精确查询布尔查询排序、分页高亮 实战案例HotelControllerIHotelServiceHotelMapperHotelHotelDocPageResu…

Google SEO优化的10大误区

以下是 Google SEO 优化的十大误区: 1、关键词堆砌: 过度使用关键词,使得内容不自然,难以阅读,同时也会被搜索引擎认为是垃圾信息,影响网站排名。 2、内容质量差: 质量差的内容会降低用户的体…

矩池云上配置FusionGan环境

1、租赁环境 2、vscode 连接 矩池云 教程:https://www.matpool.com/supports/doc-vscode-connect-matpool/ 3、进入mnt文件夹 cd ../mnt 4、克隆代码 git clone https://github.com/jiayi-ma/FusionGAN.git 如果克隆不下来,就自己下载,…

ESP32 DW1000 UWB 室内定位系统

相关软件代码下载》》 概述 在这个项目中,我们将制作一个基于 ESP32 DW1000 UWB 的室内定位系统。为此,我们将使用 2 个 UWB 锚点和 1 个 UWB 标签。当标签移动时,UWB 标签的实时位置可以使用Python 程序在PC 上以图形方式显示。 工业环境中的室内跟踪通常需要非常精确的…

C++引用的相关定义以及使用场景与指针之前的区别

一、引用的定义与特性 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。 引用的特性: 引用在定义时必须初始化一个变量可以有多个引用引用一旦引用…

电脑技巧:宽带怎么设置教程笔记,看完你就会了

宽带的设置是指将计算机连接到互联网的过程。一般来说,宽带的设置是非常简单的,只需要按照提供商的要求,正确地连接硬件和软件就可以了。下面将详细介绍如何设置宽带。 硬件设置:首先,需要连接计算机和调制解调器&…

sharding-jdbc读写分离实战

一、读写分离介绍 Sharding-JDBC读写分离则是根据SQL语义的分析,将读操作和写操作分别路由至主库与从库。它提供透明化读写分离,让使用方尽量像使用一个数据库一样使用主从数据库集群。 为了实现Sharding-JDBC的读写分离,首先,要…

Leetcode2404. 出现最频繁的偶数元素

Every day a Leetcode 题目来源&#xff1a;2404. 出现最频繁的偶数元素 解法1&#xff1a;哈希 我们构建一个这样的哈希表 unordered_map<int, int> umap&#xff1a; key&#xff1a;偶数数组元素 nums[i]value&#xff1a;nums[i]的出现次数 count 我们遍历一次数…

算法之路--快速排序算法

由于冒泡算法算法之路--冒泡算法&#xff08;算法之路--冒泡算法&#xff09;每轮都要进行从头到落位之前的每个元素的比较&#xff0c;在执行效率上需要提升&#xff0c;快速排序算法就是对冒泡算法的一种效率上的提升。 算法思路 快速排序是基于冒泡的改进&#xff0c;所以基…

力扣回溯算法专题(二)- 切割 子集问题 131.分割回文串、93. 复原IP地址、78. 子集、90. 子集Ⅱ、491.递增子序列 思路 C++实现 总结

文章目录 切割问题子集问题回溯法模板与伪代码131. 分割回文串三要素及思路回文字符串判断代码 93. 复原IP地址三要素及思路验证子串是否合法代码 78. 子集三要素及思路代码 90. 子集Ⅱ三要素及思路三种去重方式代码 491.递增子序列三要素及思路去重方式及去重优化代码 总结1. …

Django框架004:orm对mysql的增删改查

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

TypeScript 配置简述

TypeScript 配置简述 初始化项目的过程为&#xff1a; 新建一个项目 这里使用 yarn init -y 去创建一个 node 项目&#xff0c;随后使用 yarn add typescript 下载 TS 的依赖 新建一个 ts 文件 console.log(test);随意 log 一点东西进行测试 使用 tsc 编译 ts 文件 ❯ yarn …

为什么国外资深的软件测试多是手动测试,但在国内,都推崇自动化测试?

将自动化测试当成很了不起的资本&#xff0c;源于国内对Coding的崇拜 譬如一个Dev跟一个QA放在一起&#xff0c;大家的第一直观印象就是——前者的技术能力比较强。 实际上&#xff0c;这个问题分两面看&#xff1a; 自动化测试能力是不是资本&#xff1f; 当然是。 测试自动…

redis(7)

全局ID生成器: 全局ID生成器&#xff0c;是一种在分布式系统下用来生成全局唯一ID的工具&#xff0c;一般要满足以下特性 唯一性高可用(随时访问随时生成)递增性安全性(不能具有规律性)高性能(生成ID的速度快) 为了增加ID的安全性&#xff0c;我们不会使用redis自增的数值&am…

yolov4

1 V4版本概述 集各种优秀方案于一身&#xff0c;嫁接了众多主流的目标识别方面的情况。 V4 贡献 3. 数据增强策略分析 BOF Bag of freebies(BOF) Mosiac 数据增强 Mixup 比如将狗和猫的两张图片混合&#xff0c;一半猫&#xff0c;一半狗。 label 也变成 Dog 0.5 , Cat 0…

JAVA中PO、VO、BO、POJO、DAO、DTO、TO的理解

目录 1.阿里规范 1.1.Service/DAO 层方法命名规约 1.2.领域模型命名规约 1.3.命名风格 2.简单类&#xff1a;包括 DO/DTO/BO/VO 等 3.与MVC三层架构的关系 4.总结 4.1.为什么要分这些对象 4.2.什么时候需要定义这么多O 4.3.实体对象之间如何转换&#xff1f; 参考资…

Ground-aware Monocular 3D Object Detection for Autonomous Driving论文

1 摘要 摘要&#xff1a;使用单个RGB相机估计环境中物体的3D位置和方向是低成本城市自主驾驶和移动机器人的一项至关重要的挑战性任务。大多数现有算法基于二维-三维对应中的几何约束&#xff0c;这源于一般的6D目标姿态估计。我们首先确定地平面如何在驾驶场景的深度推理中提…

RT-Thread 5.0.1 qemu-virt64-aarch64 解决编译问题

前言 最近在最新的 RT-Thread 上搭建 bsp qemu-virt64-aarch64 的编译环境&#xff0c;发现较新的 gcc 交叉编译器编译失败了。 经过尝试较旧版本的 gcc 交叉编译工具链&#xff0c;终于编译通过了 下载 gcc 交叉编译工具链&#xff0c;这里推荐使用 arm 官方的 gcc 下载地址…

Apache Shiro 1.2.4反序列化漏洞(Shiro-550)--Shiro rememberMe反序列化漏洞(CVE-2016-4437)

前言 Apache Shiro是一款开源安全框架&#xff0c;提供身份验证、授权、密码学和会话管理。Shiro框架直观、易用&#xff0c;同时也能提供健壮的安全性。 Apache Shiro 1.2.4及以前版本中&#xff0c;加密的用户信息序列化后存储在名为remember-me的Cookie中。攻击者可以使用S…