声明:本文不少部分是对王巍App 架构一书的学习笔记,若有侵权,请告知程序员
构建 — 谁负责构建 model 和 view,以及将二者链接起来? 更新 model — 如何处理 view action? 改变 view — 如何将 model 的数据应用到 view 上去? view state — 如何处理导航和其余一些 model state 之外的状态?编程
“View 层和 model 层须要交流。因此,二者之间须要存在链接。假设 view 层和 model 层是被清晰地分开,并且不存在没法解耦的联结的话,二者之间的通信就须要一些形式的翻译:” 缓存
“当一个 view action 被送到 model 层时,它会被转变为model action (或者说,让 model 对象执行一个 action 或者进行更新的命令)。这种命令也被叫作一个消息 (特别在当 model 是被 reducer 改变时,咱们会这么称呼它)。将 view action 转变为 model action 的操做,以及路径上的其余逻辑被叫作交互逻辑。”架构
“当 view 依赖于 model 数据时,通知会触发一个 view 变动,来更改 view 层中的内容。这些通知能够以多种形式存在:Foundation 中的 Notification,代理,回调,或者是其余机制,都是能够的。将 model 通知和数据转变为 view 更改的操做,以及路径上的其余逻辑被叫作表现逻辑。”app
“MVC 的核心思想是,controller 层负责将 model 层和 view 层撮合到一块儿工做。Controller 对另外两层进行构建和配置,并对 model 对象和 view 对象之间的双向通信进行协调。因此,在一个 MVC app 中,controller 层是做为核心来参与造成 app 的反馈回路的:”框架
“图中的虚线部分表明运行时的引用,view 层和 model 层都不会直接在代码中引用 controller。实线部分表明编译期间的引用,controller 实例知道本身所链接的 view 和 model 对象的接口”工具
MVC 中有两个最多见的问题
学习
MVC构建
测试
“MVVM 构建的方式和 MVC 的模式很类似:controller 层充分了解程序的结构,它使用这些认知来对全部部件进行构建和链接。 MVVM 与 MVC 最大的区别可能在于 view-model 中对响应式编程的使用了,它被用来描述一系列的转换和依赖关系。经过使用响应式编程来清晰地描述 model 对象与显示值之间的关系,为咱们从整体上理解应用中的依赖关系提供了重要的指导。 具体主要有三个不一样:翻译
“MVVM 一般要求 controller 必须很是简单 (甚至简单到无需考虑)。另外,controller 必须尽量地使用库提供的绑定方法。在这样的规则的保证下,理想状况中咱们就不须要测试 controller 了,由于它没有包含咱们本身的任何逻辑。究竟应该在 controller 中留存多少逻辑,根本上来讲是掌握在程序员手上的。”
“MVVM 经过将 model 观察的代码以及其余显示和交互逻辑移动到围绕着数据流构建的隔离的类中,解决了 MVC controller 里不规则的状态交互所带来的有关问题。由于这是 MVC 中最显著的问题,并且会随着 Cocoa controller 的增大而恶化,这个变化在很大程度上缓解了 MVC 中 controller 肥大的问题。可是还有其余一些因素会使得 controller (以及 view-model) 变大,因此为了可持续发展,重构依然仍是有须要的”
MVVM的构建
关于view-model
实现状态恢复数据 在状态恢复的方法上,MVVM 中为各个 controller 所存储的数据来源于 view-model,而非像 MVC 那样来源于 controller 自己,除此以外,二者所使用的策略大抵相同。
View-model 虽然名字里既有 view 又有 model,可是它所扮演的实际上是彻彻底底的相似 controller 的角色。
View-model 从 view controller 和 view 中独立出来,也能够被单独测试。一样,view controller 也再也不拥有内部的 view state,这些状态也被移动到了 view-model 中。在 MVC 中 view controller 的双重角色 (既做为 view 层级的一部分,又负责协调 view 和 model 之间的交互),减小到了单一角色 (view controller 仅仅只是 view 层级的一部分)。
“View-model 在编译期间不包含对 view 或者 controller 的引用。它暴露出一系列属性,用来描述每一个 view 在显示时应有的值。把一系列变换运用到底层的 model 对象后,就能获得这些最终能够直接设置到 view 上的值。实际将这些值设置到 view 上的工做,则由预先创建的绑定来完成,绑定会保证当这些显示值发生变化时,把它设定到对应的 view 上去。响应式编程是用来表达这类声明和变换关系的很好的工具,因此它天生就适合 (虽然说不是严格必要) 被用来处理 view-model。在不少时候,整个 view-model 均可以用响应式编程绑定的方式,以声明式的形式进行表达。
“在理论上,由于 view-model 不包含对 view 层的引用,因此它是独立于 app 框架的,这让对于 view-model 的测试也能够独立于 app 框架。”
“在理论上,由于 view-model 不包含对 view 层的引用,因此它是独立于 app 框架的,这让对于 view-model 的测试也能够独立于 app 框架。
因为 view-model 是和场景耦合的,咱们还须要一个可以在场景间切换时提供逻辑的对象。在 MVVM-C 中,这个对象叫作协调器 (coordinator)。协调器持有对 model 层的引用,而且了解 view controller 树的结构,这样,它可以为每一个场景的 view-model 提供所须要的 model 对象。”
和 MVC 不一样,MVVM-C 中的 view controller 历来都不会直接引用其余的 view controller (因此,也不会引用其余的 view-model)。View controller 经过 delegate 的机制,将 view action 的信息告诉协调器。协调器据此显示新的 view controller 并设置它们的 model 数据。换句话说,view controller 的层级是由协调器进行管理的,而不是由 view controller 来决定的。若是咱们忽略掉协调器,那么这张图表就很像 MVC 了,只不过在 view controller 和 model 之间加入了一个阶段。MVVM 将以前在 view controller 中的大部分工做转移到了 view-model 中,可是要注意,view-model 并不会在编译时拥有对 view controller 的引用。
“初步印象来讲,由于 MVVM-C 加入了额外的一层来进行管理,看起来是比 Cocoa MVC 模式更加复杂。不过,在实现的层级,若是你可以始终如一地贯彻这个模式,代码会变得更简单一些。啊,这里说的简单并不意味着容易,只有当你对常见的响应式代码变形熟悉之后,才不会对书写代码感到无从下手,才不会对调试问题感到懊恼沮丧。不过,从使人高兴的一面来讲,精心设计的数据管道一般不容易产生错误,在长期来看维护也更容易一些。”
“iOS 中的协调器是一种颇有用的模式,由于管理 view controller 层级是一件很是重要的事情。协调器在本质上并无和 MVVM 绑定,它也能被使用在 MVC 或者其余模式上。”
协调器为每一个 controller 的 view-model 设置初始的 model 对象。 View-model 将设定值和其余 model 数据及观察量进行合并。 View-model 将数据变形为 view 所须要的精确的格式。 Controller 将准备好的值绑定到各个 view 上去。
对于Controller层过于臃肿的问题,MVP模式则能较好地解决这个问题——既然UIViewController和UIView是耦合的,索性把这二者都归为View层,业务逻辑则独立存在于Presenter层,Model层保持不变。下图比较清除得展现了MVP模式的结构
“model 适配器 - view 绑定器 (ModelAdapter-ViewBinder, MAVB)”
Elm 架构 (TEA)、VIPER、Riblets
“响应式编程是一种用来交流变动的工具,不过和通知或者 KVO 不一样的是,它专一于在源和目标之间进行变形,让逻辑能够在部件之间传输信息的同时得以表达。” “响应式编程是一种用来描述数据源和数据消费端之间数据流动的模式” “数据变形的部分是响应式编程所能带来的最大优点,但同时它也是学习曲线最为陡峭的部分。”