ios - 为什么在 iOS 中使用 View 模型 (MVVM)?

标签 ios cocoa-touch mvvm

因为 Swift/Objective-C 支持编写扩展,所以我在模型的扩展类中编写“ViewModel”属性,并在通常使用 ViewModel 的地方使用此扩展。

我知道扩展程序不能存储属性。但大多数 MVVM 架构无论如何都不建议在 ViewModel 中存储属性(除了那些用于缓存的属性)。

维护单独的 ViewModel 对象的主要问题是使其与模型同步。是的,有很多第三方框架可以帮助使用响应式(Reactive)编程技术进行同步。但对于简单地使用扩展就能解决的问题,为什么要使用重型框架来实现同样的效果呢?

我的基于扩展的 MVVM 架构并未遇到障碍。你们中有人尝试过这个并转向响应式编程架构吗?

最佳答案

我在扩展方法方面的糟糕经历是 my March 2016 talk at iOSoHo in New York 第一个也是最重要的部分的基础。我所说的有关扩展的大部分内容并不在幻灯片中。扩展方法存在几个问题:

  1. 您只能有一个模型到 View 的映射(没有另一个中间层来提供协调扩展属性的逻辑)。这极大地损害了 View 的可重用性。
  2. 关于第 1 点,即使您围绕这一点进行协调,如果您在很多地方使用该模型,例如 name,然后添加 ,您也可能会发生冲突firstNameOnly 等。如果您想采用这种方式,模型绝对只能以一种方式符合协议(protocol)。
  3. 提供虚拟值来代替模型来进行自动布局、调试、错误情况等,几乎是不可能的。您可能会发现自己正在为此编写一个结构——那就是 ViewModel。
  4. 如果您的 View 需要多个模型来填充它,或者需要模型外部的信息,则 View 模型可以简化它们的协调。

有了 ViewModel,这些重要的情况就变得微不足道了。 (在演讲中,我称之为“命令”,因为它们完全符合四组设计模式命令的定义;设计模式注释也称为操作,即 UIAlertAction。)

我认为“ViewModel”应该是轻量级的、不可变的,并且通过单向数据流分布。它们存储了属性,但这只是为了移动数据,虚拟机本身是不可变的且一次性的。这类似于 Facebook 在 2017 年 3 月的 iOSoHo 上提到的方法,尽管我认为他们不称其为 View 模型,而只是称其为轻量级对象。您可以在那里放置更复杂的逻辑,但实际上最好最多调用其他地方处理的更复杂的逻辑。

我认为很关键的一个补充是,我的规则是“ViewModel”,无论你怎么调用它,都应该没有程序员在查看线框图时无法编写的属性。所以 var dateString : String 不是 var date : NSDate。这是我在幻灯片中厚颜无耻的术语“模态对象属性转换器”。但这有助于记住一个严肃的观点:一座城堡需要能够升起吊桥并在被围困时继续前进;当网络断开(或尚不存在)时, View 需要完全发挥作用。在很多情况下,你会比你的 View 能做到这一点更容易。

就在几周前,我采用了这种方法,并能够在大约 4 天内创建多个复杂的屏幕,仅根据设计工作,最终将由来自网络的数据填充,但目前没有任何模型或网络层。当数据层准备就绪时,我可以简单地编写一些创建方法 init(with: Model) 或更好的 static func withModelforCase1(_ model: Model) -> ViewModel 并编写创建方法中的映射,然后在连接模型时,将 static func debugCase1() -> ViewModel 替换为这些创建方法。随着模型的发展,编译器只会在这里抛出错误;随着 View 的发展,调整 ViewModel,编译器将再次在这里且仅在此处抛出错误。无需触及其他代码。

扩展一开始看起来非常优雅,但实际上在模型和 View 之间创建了紧密耦合。某种 ViewModel 方法是一个强大的系统,可以满足现代 iOS 应用程序以及现代 iOS 应用程序开发的需求。

关于ios - 为什么在 iOS 中使用 View 模型 (MVVM)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44716810/

相关文章:

iphone - 带有旋转 UI 元素的 AutoLayout

ios - 如何设置UIButton按下后高亮状态

c# - 使 Command 的 CanExecute 依赖于其他字段的值

ios - 以编程方式创建 UIScrollView 作为另一个 UIView 的 subview 的必要步骤是什么?

ios - 背景图片大小 Sprite Kit Game

ios - iOS 上嵌入 YouTube 视频的媒体回调

ios - 没有渐变的 UIView 中的阴影?

C# 和 Caliburn - RescueAttribute 和协程

wpf - 具有相同 ViewModel 的多个 View

ios - AWS S3 SDK链接器问题