赞
踩
原文网址:http://www.teehanlax.com/blog/model-view-viewmodel-for-ios/
在图解里,视图作为通知任何用户交互的控制器。然后视图控制器更新模型来体现状态的变化。然后该模型(通常是通过键 - 值观察)通知所有控制器,他们需要对自己的视图进行更新。这种协调方式构成了很多写在iOS应用程序里面的代码。
模型对象通常是非常,非常简单的。很多时候,他们是核心数据管理对象,或者,如果你比较喜欢避开核心数据和其他普遍的模型。更具苹果的说法,模型用包含的数据和逻辑来处理这些数据。在实践中,模型往往很稀疏,不管这样是好是坏,控制器得到了模型的逻辑。
视图(通常情况下)是UIKit组件或者程序员定义的UIKit组件集合其中之一。他们通常拼凑到你的.xib或者.Storyboard中:视觉和应用程序交互的组件。按钮。标签。你有一个想法,视图应该永远不会被模型直接引用,控制器应该只通过IBAction触发事件。不属于视图本身的业务逻辑不应该在那里。
就这样我们舍弃了控制器。控制器是一个应用程序的“粘合剂代码”:它在模型和视图之间协调所有的交互,控制器负责管理他们自己视图的视图层次结构。他们响应视图的加载,出现,消失等等。他们倾向于用模型逻辑来装载,我们避免我们的模型和业务逻辑远离我们的观点。这是我们与MVC的第一个问题…
大规模的视图控制器
因为在视图控制器中放置的代码量非常大,他们往往会变得很臃肿,在iOS中有的视图控制器中的代码,可能会延展至成千上万代码行。你应用程序中这些臃肿的片段权衡下来:大规模的视图控制器都难以维持(因为他们的规模太庞大),其中含有很多属性,会让他们的状态很难被管理,又符合许多协议,混合了协议的响应代码与控制器的逻辑。
大规模的视图控制器是很难测试的,不管是手动测试还是单元测试,因为他们有很多可能的状态。把你的代码分割的更少,更小更简单通常是一件很好的事情。
缺少网络逻辑
MVC的定义 - 苹果使用的那个 - 规定所有对象可以被分类为一个类型,一个视图,或者一个控制器。所有这些。所以,你应该吧网络代码放在哪里呢?而代码与API的通信又在哪里呢?
你可以试着巧妙的把它放在模型对象里,但是这么做可能会变得很棘手,因为网络调用应该是异步的过程。所以,如果一个网络请求会超越拥有它的模型,好吧,它变复杂了。你绝对不应该把网络代码放进视图里,所以…应该留给控制器来处理。这是一个不好的想法,因为它会促使我们产生大规模的视图控制器这个问题。
那么,在哪里呢?对于代码来说,MVC的这三个组成部分没有一个地方不适合代码。
MVVM来自微软,但不要坚决反对使用它。MVVM和MVC非常相似。它让视图和控制器具有一定形式的紧密耦合的性质,并且还引入了一个新的组件。
视图模型是作为用户输入验证逻辑的好地方,通过视图呈现逻辑,附加的网络请求,和其他复杂的代码。有一件事是,视图本身在视图模型中不属于任何视图的引用。视图模型中的这个逻辑对于iOS和OS X中应该是同样适用的。(换一种说法,不要在你的视图模型中#import UIKit.h,你会被罚款的)。
由表现逻辑,比如映射一个模型值去格式化一个东西--属于视图模型中,视图控制器本身会变得很大,但是并非臃肿。最好的部分是当你使用MVVM,你可以放置一小部分逻辑在你的视图模型中,当你成为越来越适合的范例时再把它们迁移过来。
使用MVVM编写的iOS应用程序是高度可测试的;因为视图模型包含了所有的演示逻辑并且不引用这个视图,它可以通过编程进行全面测试。虽然很多黑客参与测试Core Data模型,但是使用MVVM编写的应用程序完全可以进行单元测试。
在我的经验中,使用MVVM的结果是,代码的总量略有增加,但在代码的复杂性部分整体下降。这是一个权衡过后很核算的方法。
如果你再回头看看MVVM图解,你会发现,我用了模棱两可的动词“通知”和“更新”,但是没有支出应该怎么做。你可以用KVO,就像MVC,但是很快就会变得很难管理。在实践中,使用ReactiveCocoa是把所有模块粘合在一起的一个好方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。