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

iOS - MVP 架构模式

1、MVP

  • 从字面意思来理解,MVP 即 Modal View Presenter(模型 视图 协调器),MVP 实现了 Cocoa 的 MVC 的愿景。MVP 的协调器 Presenter 并没有对 ViewController 的生命周期做任何改变,因此 View 可以很容易的被模拟出来。在 Presenter 中根本没有和布局有关的代码,但是它却负责更新 View 的数据和状态。MVC 和 MVP 的区别就是,在 MVP 中 M 和 V 没有直接通信。

  • MVP 是第一个如何协调整合三个实际上分离的层次的架构模式,既然我们不希望 View 涉及到 Model,那么在显示的 View Controller(其实就是 View)中处理这种协调的逻辑就是不正确的,因此我们需要在其他地方来做这些事情。例如,我们可以做基于整个 App 范围内的路由服务,由它来负责执行协调任务,以及 View 到 View 的展示。这个出现并且必须处理的问题不仅仅是在 MVP 模式中,同时也存在于以下集中方案中。

  • 1)MVP模式下的三个特性的分析:

    • 任务均摊 -- 我们将最主要的任务划分到 Presenter 和 Model,而 View 的功能较少;
    • 可测试性 -- 非常好,由于一个功能简单的 View 层,所以测试大多数业务逻辑也变得简单;
    • 易用性 -- 代码量比 MVC 模式的大,但同时 MVP 的概念却非常清晰。
  • 2)iOS MVP 示意图:

    MVP1

    • 就 MVP 而言,UIViewController 的子类实际上就是 Views 并不是 Presenters。这点区别使得这种模式的可测试性得到了极大的提高,付出的代价是开发速度的一些降低,因为必须要做一些手动的数据和事件绑定。

    • 还有一些其他形态的 MVP -- 监控控制器的 MVP。这个变体包含了 View 和 Model 之间的直接绑定,但是 Presenter 仍然来管理来自 View 的动作事件,同时也能胜任对 View 的更新。

      MVP2

  • 3)规范的 MVP 设计模式:

    • 1、View 层比较简单明,就是 View 的一些封装、重用。在一款精心设计过的 App 里面,应该有很多 View 是可以封装重用的。比如一些自己的 TableViewCell,自己设计的 Button,一些 View(包含一些子 View,UI 精心设计过,在项目里多处出现的)等等。

    • 2、Model 层应该不仅仅是创建一个数据对象,还应该包含网络请求,以及数据 SQLite 的 CRUD 操作(比如 iOS 平台,一般以 FMDB 框架直接操作 sql,或者用 CoreData) 。一般可以将数据对象是否需要缓存设计成一个字段 isCache,或者针对整个项目设计一个开存储关,决定整个项目是否需要数据缓存。我们常见的新闻类 App,在离线的时候看到的数据,都是做了缓存处理的。比如一些金融类的 App,实时性比较高,是不做缓存的。

    • 3、Presenter 层并不涉及数据对象的网络请求和 SQLite 操作,只是 Model 层和 View 层的一个桥梁。Presenter 层就不至于太臃肿,容易看懂。一些大的 App,或因为上线时间比较久了,经历过众多程序员的修补,或因前期并未做好架构,以至于打开一个类,几千行的代码,看着自己都晕。

相关文章:

  • <component :is=“动态组件“></component>
  • 大数据解决方案如何满足零售行业进销存数据的实时性存储与更新
  • react项目中实现打印预览功能
  • easyUI loyout tabs自适应宽度
  • react封装一个打印功能
  • 在linux环境下编译C++ 程序
  • react项目中,在tab列表上展示某个字段以 数组形式 展示
  • Spark Streaming官方文档学习--下
  • Vue 判断两个时间选择框的校验element 。开始时间不能大于结束时间
  • 为什么不能访问django自带的索引页
  • SSIS 数据类型和类型转换
  • Vue,列表展示。多个字段拼接展示
  • Swift开发:NSLayoutConstraint纯代码实现自动布局-初级篇
  • react中的 Modal.confirm
  • 数据挖掘之决策树ID3算法(C#实现)
  • create-react-app做的留言板
  • ESLint简单操作
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • jdbc就是这么简单
  • Js基础——数据类型之Null和Undefined
  • js面向对象
  • maven工程打包jar以及java jar命令的classpath使用
  • MySQL主从复制读写分离及奇怪的问题
  • Netty 4.1 源代码学习:线程模型
  • passportjs 源码分析
  • Python实现BT种子转化为磁力链接【实战】
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 力扣(LeetCode)357
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 入手阿里云新服务器的部署NODE
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 微服务框架lagom
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 通过调用文摘列表API获取文摘
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (八十八)VFL语言初步 - 实现布局
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (蓝桥杯每日一题)love
  • (三) diretfbrc详解
  • (生成器)yield与(迭代器)generator
  • (图)IntelliTrace Tools 跟踪云端程序
  • (原)Matlab的svmtrain和svmclassify
  • (转)为C# Windows服务添加安装程序
  • ***监测系统的构建(chkrootkit )
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .cn根服务器被攻击之后
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .Net6使用WebSocket与前端进行通信
  • .net打印*三角形
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • [ 攻防演练演示篇 ] 利用通达OA 文件上传漏洞上传webshell获取主机权限
  • [.net]官方水晶报表的使用以演示下载