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

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的简要介绍。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智能安防无人机——一种安防巡检新方案

在高新技术的推动下,安防无人机在监控、巡逻等领域的使用频率越来越高,逐渐成为安防救援的重要帮手。安防无人机作为城市安全应急保障体系的重要组成部分,在未来将变得不可或缺。 一、安防无人机的定义及构成 复亚智能无人机全自主巡飞系统由…

【android开发-01】android中toast的用法介绍

1,android中toast的作用 在Android开发中,Toast是一种用于向用户显示简短消息的轻量级对话框。它通常用于向用户提供一些即时的反馈信息,例如操作结果、提示或警告。 Toast的主要作用如下: 提供反馈:Toast可以在用户…

wordpress安装之Linux ftp传输

工欲善其事,必先利其器。 最近准备在自己的服务器上搭建一个个人技术分享的平台。 因为我发现现在网络上的工具呀,还有一些问题的解答总是模棱两可,所以我打算自己做一个。 首先呢,我们需要有一个linxu的系统当服务器,然后呢&a…

LV.12 D21 PWM实验 学习笔记

一、PWD简介 1.1 蜂鸣器工作原理 有源蜂鸣器 有源蜂鸣器只要接上额定电源就可以发出声音 无源蜂鸣器 无源蜂鸣器利用电磁感应原理,为音圈接入交变电流后形成的电磁铁与永磁铁相吸或相斥而推动振膜发声 1.2 使用GPIO控制 while(1) { GPX2.DATGPX2.D…

certbot—30秒部署你的HTTPS,永久免费,自动续约

在之前我已经介绍过部署反向代理的2种方式了。第一种是通过宝塔的反向代理配置然后开启HTTPS。 第二种是通过nginxproxymanager。 今天要给大家分享的是一个 certbot。 Certbot 是一个由 Lets Encrypt 开发的免费开源工具,用于自动化部署和管理 SSL/TLS 证书。它具有…

16、什么是损失函数

上一节介绍了训练的过程,一个模型在训练的过程中,每一轮训练数据计算到到最后一层时,都会输出本轮的预测值,那么如何将本轮的预测值与标签中的真实值进行对比呢? 这就要用到损失函数(Loss function)。 什么是损失函数 损失函数是用来衡量模型预测结果与真实标签(grou…

linux 内核工作队列技术原理

首先介绍一下工作队列使用的术语。 work:工作,也称为工作项。work queue:工作队列,就是工作的集合, work queue 和 work 是一对多的关系。worker: 工人, 一个工人对应一个内核线程,…

MIAOYUN荣获“2023中国赛宝信息技术应用创新优秀解决方案应用创新示范方向三等奖”

11月30日,2023(第四届)数字化转型推动高质量发展大会在中国海口成功召开,会上举办了2023中国赛宝信息技术应用创新优秀解决方案征集活动颁奖仪式。成都元来云志科技有限公司(简称“MIAOYUN”)联合国网浙江省…

15、 深度学习之正向传播和反向传播

上一节介绍了训练和推理的概念,这一节接着训练和推理的概念讲一下,神经网络的正向传播和反向传播。 其实单看正向传播和反向传播这两个概念,很好理解。 正向传播(Forward Propagation)是指从输入层到输出层的数据流动过程,而反向传播(Backpropagation)是指数据从输出…

element ui el-date-picker日期时间选择器 设置只能选择不大于30天时间范围

需求&#xff1a;要求日期时间选择器只能选择最多32天&#xff0c;其他日期为不可点击状态。 日期组件type为daterange或者datetimerange都生效 实现&#xff08;vue2.x&#xff09;&#xff1a; 通过属性picker-options html <el-date-pickerv-model"dateTime&qu…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之存储管理(2)》(15)

[TOC](《Linux操作系统原理分析之存储管理&#xff08;2&#xff09;》&#xff08;15&#xff09; 5 存储管理5.4 分页存储管理5.4.1 纯分页存储管理a.页&#xff08;页面&#xff09;和物理块&#xff08;帧&#xff09;b. 页面大小c. 逻辑地址结构 5.5 存储扩充技术5.5.2 交…

spring cache 学习 —— @Cacheable 使用详解

1. 功能说明 Cacheable 注解在方法上&#xff0c;表示该方法的返回结果是可以缓存的。也就是说&#xff0c;该方法的返回结果会放在缓存中&#xff0c;以便于以后使用相同的参数调用该方法时&#xff0c;会返回缓存中的值&#xff0c;而不会实际执行该方法。 注意&#xff0c;这…

上门预约洗鞋店小程序

互联网洗鞋店小程序开发&#xff0c;结合洗鞋行业线下实际运营情况和经验&#xff0c;专为洗鞋人、洗鞋店打造的高效、实用、有价值的洗鞋私域流量管理软件系统。 帮助洗鞋人建立自己的私域流量&#xff0c;实现会员用户管理&#xff0c;用户与商家点对点互联互通&#xff0c;提…

okhttp导致的内存溢出(OOM)sun.security.ssl.SSLSocketImpl

使用分析工具&#xff1a;MAT(Memory Analyzer Tool)、JvisualVM占用内存&#xff1a;sun.security.ssl.SSLSocketImpl 一、 项目场景&#xff1a; 功能&#xff1a;一个定时任务(xxl-job)采用线程池的方式多线程请求第三方拉取数据&#xff0c;网络框架使用okhttp3。 问题&am…

从零开发短视频电商 在AWS上用SageMaker部署开源模型并用Java SDK调用

文章目录 1.创建AWS账户2.登录AWS3.创建域4.部署模型方式一 使用JumpStart可视化界面部署内置的模型方式二 采用python脚本部署私有模型5.调用模型AWS Java SDK调用Http调用6.监控7.自动扩缩容1.创建AWS账户 需要准备好邮箱一个,支持visa功能的信用卡一个。然后到aws上自己去…

手动部署1个Cloud Run service

什么是Cloud Run 来自chatgpt&#xff1a; Google Cloud Run 是一项全托管的服务器托管平台&#xff0c;它允许您在容器化的环境中运行无服务器应用程序。Cloud Run 提供了一种简单而灵活的方式来构建、部署和扩展应用程序&#xff0c;无需管理底层基础设施。 以下是 Cloud …

Linux-Linux安装JDK及配置环境 及 遇到的问题

下载linux环境对应的JDK的tar.gz包 配置JDK环境&#xff1a;编辑 sudo vim /etc/profile 在文件的最下方&#xff0c;填写 export JAVA_HOME/usr/local/src/software/jdk1.8 export CLASSPATH.:$JAVA_HOME/lib/tools.jar export PATH$JAVA_HOME/bin:$PATH 执行生效命令&…

2024年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-B卷

2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-B卷 2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-B卷A 模块基础设施设置/安全加固&#xff08;200 分&#xff09;A-1&#xff1a;登录安全加固&#xff08;Windows…

电商店铺搬家API接口,轻松搬运淘宝1688京东拼多多等平台全站商品丨商品详情业数据接口丨搜索商品列表数据接口

轻松搬运淘宝、1688、京东、拼多多等平台全站商品的API接口通常是由各平台提供的官方开发工具或第三方工具提供的。 对于淘宝和1688平台&#xff0c;可以使用淘宝开放平台&#xff08;Open Platform&#xff09;提供的API接口来访问和操作商品信息。淘宝开放平台提供了丰富的A…

基于通义千问和向量数据构建问答知识库

参考&#xff1a;Java从0到1构建基于ChatGPT向量数据库的检索增强生成模型RAG-02 - 知乎 (zhihu.com) 1、先开通 阿里云的向量检索服务 如何开通向量检索服务并创建API-KEY_向量检索服务-阿里云帮助中心 (aliyun.com) 按流程申请 最后需要申请API-KEY 安装DashVector SDK M…