iOS简单理解区分MVC、MVP、MVVM

news2024/11/18 7:50:48

MVC、MVP、MVVM

前言

这篇文章简单介绍MVC、MVP和MVVM三种架构,并配上一个简单的Swift demo来区分MVC和MVVM两种架构。

MVC

传统MVC

下图是传统结构MVC,可以看到这种结构是紧耦合的,不推荐使用。

传统的MVC

苹果的MVC

如下图,这是苹果MVC架构的愿景,Controller作为View和Model的中介,这样它们就解耦了。

Cocoa MVC

各层的职责如下所示:

  • Model: 数据层,负责数据的处理和获取的数据接口层。
  • View: 展示层(GUI),对于 iOS 来说所有以 UI 开头的类基本都属于这层。
  • Controller: 控制器层,它是 Model 和 View 之间的胶水或者说是中间人。一般来说,当用户对 View 有操作时它负责去修改相应 Model;当 Model 的值发生变化时它负责去更新对应 View。

如上图所示,M和View应该是完全隔离的,由C作为中间人来负责二者的交互,同时三者是完全独立分开的,这样可以保证M和V的可测试性和复用性。

MVC在iOS中的实现

由于Apple的规范,一个界面的呈现都需要构建一个viewcontroller,而每个viewcontroller都带有一个根view,这就导致C和V紧密耦合在一起构成了iOS里面的C层,这明显违背了MVC的初衷。实际结构如下图。

img

根据苹果对MVC架构规范的描述,原文戳这里,viewcontroller其实是view和controller的组合,目的就是为了提高开发效率,简化操作。但这样也会导致一个问题,就是View层的代码全堆到了VC,比如VC中构建View,View的显示逻辑处理等等。

MVC各层功能

controller层(VC)
  • 生成view,然后组装view
  • 响应View的事件和作为view的代理
  • 调用model的数据获取接口,拿到返回数据,处理加工,渲染到view显示
  • 处理view的生命周期
  • 处理界面之间的跳转
model层
  • 业务逻辑封装
  • 提供数据接口给controller使用
  • 数据持久化存储和读取
  • 作为数据模型存储数据
view层
  • 界面元素搭建,动画效果,数据展示,
  • 接受用户操作并反馈视觉效果

关于Model层,这里有一段文章引用说明了真正的Model层实际不应该只有几个结构和属性,应该有的是数据的业务逻辑。

理解Model层:

首先要正确的理解MVC中的M是什么?他是数据模型吗?答案是NO。他的正确定义是业务模型。也就是你所有业务数据和业务实现逻辑都应该定义在M层里面,而且业务逻辑的实现和定义应该和具体的界面无关,也就是和视图以及控制之间没有任何的关系,它是可以独立存在的,您甚至可以将业务模型单独编译出一个静态库来提供给第三方或者其他系统使用。

在上面经典MVC图中也很清晰的描述了这一点: 控制负责调用模型,而模型则将处理结果发送通知给控制,控制再通知视图刷新。因此我们不能将M简单的理解为一个个干巴巴的只有属性而没有方法的数据模型。

其实这里面涉及到一个最基本的设计原则,那就是面向对象的基本设计原则:就是什么是类?类应该是一个个具有不同操作和不同属性的对象的抽象(类是属性和方法的集合)。 我想现在任何一个系统里面都没有出现过一堆只有数据而没有方法的数据模型的集合被定义为一个单独而抽象的模型层来供大家使用吧。 我们不能把一个保存数据模型的文件夹来当做一个层,这并不符合横向切分的规则。

Model层实现的正确姿势:

  1. 定义的M层中的代码应该和V层和C层完全无关的,也就是M层的对象是不需要依赖任何C层和V层的对象而独立存在的。整个框架的设计最优结构是V层不依赖C层而独立存在,M层不依赖C层和V层独立存在,C层负责关联二者,V层只负责展示,M层持有数据和业务的具体实现,而C层则处理事件响应以及业务的调用以及通知界面更新。三者之间一定要明确的定义为单向依赖,而不应该出现双向依赖
  2. M层要完成对业务逻辑实现的封装,一般业务逻辑最多的是涉及到客户端和服务器之间的业务交互。M层里面要完成对使用的网络协议(HTTP, TCP,其他)、和服务器之间交互的数据格式(XML, JSON,其他)、本地缓存和数据库存储(COREDATA, SQLITE,其他)等所有业务细节的封装,而且这些东西都不能暴露给C层。所有供C层调用的都是M层里面一个个业务类所提供的成员方法来实现。也就是说C层是不需要知道也不应该知道和客户端和服务器通信所使用的任何协议,以及数据报文格式,以及存储方面的内容。这样的好处是客户端和服务器之间的通信协议,数据格式,以及本地存储的变更都不会影响任何的应用整体框架,因为提供给C层的接口不变,只需要升级和更新M层的代码就可以了。比如说我们想将网络请求库从ASI换成AFN就只要在M层变化就可以了,整个C层和V层的代码不变。

MVP

结构如下图。

Passive View 变体 — MVP

MVC中没有对业务逻辑和业务展示进行区分,MVP就是针对这一点进行的优化,它将业务逻辑和业务展示做了一层隔离。M和V功能不变, 原来的C现在只负责布局, 而所有的业务逻辑全都转移到了P层。P层处理完了业务逻辑,如果要更改view的显示,那么可以通过回调来实现,这样可以减轻耦合,MVP从视图层中分离了行为(事件响应)和状态(属性,用于数据展示),它创建了一个视图的抽象,也就是presenter层,而视图就是P层的『渲染』结果。P层中包含所有的视图渲染需要的动态信息,包括视图的内容(text、color)、组件是否启用(enable),除此之外还会将一些方法暴露给视图用于某些事件的响应。

MVP通信过程

img

  1. 当视图接收到来自用户的事件时,会将事件转交给 Presenter 进行处理;
  2. 被动的视图实现presenter的代理,当需要更新视图时 Presenter回调代理来更新视图的内容,这样让presenter专注于业务逻辑,view专注于显示逻辑
  3. Presenter 负责对模型进行操作和更新,在需要时取出其中存储的信息
  4. 当模型层改变时,可以将改变的信息发送给观察者 Presenter

MVVM

MVVM由三个部分组成,也就是 Model、View 和 ViewModel;其中视图模型(ViewModel)其实就是 MVP 模式中的P,在 MVVM 中叫做VM,架构图如下。

img

MVVM相对于MVP做的改进就是对VM/P和view做了双向的数据和命令绑定,利用Binder机制使得Model和View可以状态同步。

具体实例看MVC与MVP/MVVM的实现对比

acc4309009746c0a5870c637ecee5955

可以看到项目中,MVVM比MVC多了一个ViewModel层,这是两者的不同,我们先来看看相同的Model和ViewController,两者除了命名不同其他的都相同,所以以下只展示一种。

Model

39fd8c1f81071de0e1bf7eb531986e5e

ViewController

3d622c59990f8b57adcd77f9b1072cbc

fetchData部分写的内容是模拟网络请求数据,代码如下图。

fetchData

fb553ca7ab781e35740ca3e5fcd96ead

接下来让我们看到MVC中的View层

MVCView

0bf5b3ed1c2e294058b09ae28e4a91ac

可以看到在这里对业务的显示和业务的逻辑处理都放在了View层。

我们反观MVVM架构中,加入了一个ViewModel,它对业务逻辑部分抽象出了一个类,代码如下。

cdc371f737ec6549762c0c7bbb3a2166

最后我们在View中,只用处理业务展示部分即可,代码如下。

ee004282b845b4a90138f557e8de24dc
以上就是MVC、MVP、MVVM的简要介绍。

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

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

相关文章

【翻译】直流电动机的控制

直流电(DC)电机由于其转矩易于控制,速度控制范围广,已广泛应用于可调速驱动或可变转矩控制中。然而,直流电机有一个主要的缺点,即它们需要机械装置,如换向器和刷子来连续旋转。这些机械部件需要…

windows配置go调用python的编译环境

go是支持调用python代码的,之前写了几篇linux的部署教程,因为觉得windows的不复杂就没有写,结果今天新部署一个Windows的环境,有些步骤想不起来了,好记性不如烂笔头,还是记录一下吧。 这些是之前写的linux…

FlowJo软件的简单介绍 掌控流式细胞分析的科技巨匠 FlowJo10

FlowJo 10 for Mac是一款强大的流式细胞数据分析软件,具有以下功能: 数据导入与预处理:FlowJo 10可以轻松导入各种类型的流式细胞数据,并对数据进行预处理,包括去噪、背景校正等,以确保数据的准确性和可靠…

STM32F407-14.3.9-01输出比较模式

输出比较模式 此功能用于控制输出波形,或指示已经过某一时间段。 当捕获/比较寄存器与计数器之间相匹配时,输出比较功能: ● 将为相应的输出引脚分配一个可编程值,该值由输出比较模式(TIMx_CCMRx 寄存器中的 OCxM⑦…

[网鼎杯 2020 青龙组]singal 1

前言 在主函数中找到了一个vm的译码器,译码器主要是解释传入的opcode,然后对我们输入的字符操作,这里我们发现他是单字节比较的,方法很多可以使用单字节映射,也可以是使用符号化执行,当然也可以硬着头皮去…

Docker 环境中 Spring Boot 应用的 Arthas 故障排查与性能优化实战

🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🌺 仓库主页: Gitee 💫 Github 💫 GitCode 💖 欢迎点赞…

EasyExcel两行表头

例子: 代码: StorageService localStorageService storageFactory.getLocalStorageService();String path "";// 文件信息String dateTime DateUtils.formatTimestampToString(new Date());String title "xxx统计";String fil…

TZOJ 1379 C语言合法标识符

答案&#xff1a; #include <stdio.h> #include <string.h> int main() {char arr[60];int n 0, i 0, num 0, flag;scanf("%d", &n);getchar(); //读取回车键while (n--) //循环N次{gets(arr);num strlen(arr); //num为字符串长度flag 1; …

Echarts大屏可视化_05 折线图的定制开发

继续跟着pink老师学习Echarts相关内容&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 折线图1 1.引入 折线图选取示例地址 标题没有用到就给他删了 直接引入 注意这里是line下面的chart 获取dom元素一定不…

java餐饮刀削面快餐店点餐服务系统springboot+jsp

网上点餐省去了客户很多不必要的时间和麻烦&#xff0c;给商家带来更多利益。同时&#xff0c;网上点餐可以辅助餐饮企业营销。传统的点餐是需要配备一个专业的服务员负责菜品介绍并记录顾客点单&#xff0c;确认后上交至后台厨房&#xff0c;厨房根据菜品种类安排做菜顺序最终…

Spring 多数据源搭建

目录 前言 正文 1.Druid 介绍和使用 2.其他多数据源解决方案 总结 前言 对于复杂的业务和项目&#xff0c;可能在一个单体项目中存在需要连接多个数据库的情况。这时&#xff0c;就会使用到多数据源&#xff0c;实际中遇到的可能性比较大。 正文 如果一个项目中需要连…

Unity Image - 镜像

1、为什么要使用镜像 在游戏开发过程中&#xff0c;我们经常会为了节省 美术图片资源大小&#xff0c;美术会将两边相同的图片进行切一半来处理。如下所示一个按钮 需要 400 * 236&#xff0c;然而美术只需要切一张 74*236的大小就可以了。这样一来图集就可以容纳更多的图片。…

Centos7使用阿里云镜像加速服务安装Docker

文章目录 一、前提说明二、安装docker1、创建docker文件夹2、安装所需的软件包3、设置Docker仓库4、安装docker5、启动验证使用阿里云镜像加速服务 三、卸载docker 一、前提说明 需要先安装好虚拟机&#xff0c;可以查看这篇https://blog.csdn.net/qq_36433289/article/detail…

Docker的常用基本命令(基础命令)

文章目录 1. Docker简介2. Docker环境安装Linux安装 3. 配置镜像加速4. Docker镜像常用命令列出镜像列表搜索镜像下载镜像查看镜像版本删除镜像构建镜像推送镜像 5. Docker容器常用命令新建并启动容器列出容器停止容器启动容器进入容器删除容器&#xff08;慎用&#xff09;查看…

Java-easyExcel入门教程

文章目录 前言一、简介二、使用步骤1. 引入依赖2. 前提准备3. 实现导出4. 实现导入 三、我所遇到的问题四、总结 前言 在日常开发中经常会遇到一些 excel 表导入导出的需求&#xff0c;以往会使用 POI 封装成工具类来处理这些导入导出的需求&#xff0c;但是 POI 在导入大文件…

WSL2+tensorflow-gpu 2.3.0 C++ 源码编译

wsl2已有gcc 版本为9.4.0&#xff0c;但tensorflow2.3.0需对应gcc7.3.1 tensorflow与cuda cudnn python bazel gcc版本对应关系 故需下载一个低版本的gcc&#xff0c;但同时还想保留较高版本的gcc&#xff0c;那么参考文章&#xff1a;深度学习环境搭建(二): Ubuntu不同版本g…

【笔记】2023最新Python安装教程(Windows 11)

&#x1f388;欢迎加群交流&#xff08;备注&#xff1a;csdn&#xff09;&#x1f388; ✨✨✨https://ling71.cn/hmf.jpg✨✨✨ &#x1f913;前言 作为一名经验丰富的CV工程师&#xff0c;今天我将带大家在全新的Windows 11系统上安装Python。无论你是编程新手还是老手&…

HBase安装配置:一键自动安装配置

使用shell脚本一键下载、安装、配置HBase&#xff08;单机版&#xff09; 1. 把下面的脚本复制保存为/tmp/install_hbase.sh文件 #!/bin/bash# 安装之前确保安装目录有写入权限&#xff0c;若没有&#xff0c;自行增加 # 安装版本 zk_version"2.4.8" # 安装目录 zk…

5G承载网和大客户承载的演进

文章目录 移动4/5G承载网联通和电信4/5G承载网M-OTN&#xff08;Metro-optimized OTN&#xff09;&#xff0c;城域型光传送网PeOTN&#xff08;packet enhanced optical transport network&#xff09;&#xff0c;分组增强型OTN板卡增强型PeOTN集中交叉型PeOTN VC-OTN&#x…

如何从 Android 手机恢复已删除的视频

您是否曾经丢失过手机中的任何数据&#xff1f;如今&#xff0c;由于 Android 上的应用程序崩溃、根进程停止、Android 更新失败等等&#xff0c;数据丢失很普遍。错误删除是丢失视频、录音和音乐副本的另一种可能的方式。 丢失包含有关新完成的项目的重要信息的视频或婚礼、周…