Model-View-Controller (MVC) in iOS: A Modern Approach

原文连接ios


这篇文章将帮助你避免App中常见的致使不易扩展的错误。你将会学到当你建立一个App时该怎么作,不应怎么作的最佳实践。安全

读完这篇文章你能学到在app中使用最新最好的实践。避免结构上的问题。网络

MVC101

模型是数据存放的地方。持久化、模型对象、解析器和网络相关代码这些东西一般放在这里。mvc

视图是app的界面。这些类能被复用,通常不存放特定业务的逻辑。app

控制器在模型和视图之间进行调解,典型的是经过代理模式。理想状况下,控制器实体不会知道它处理的实体视图。相反,它会经过代理和抽象视图交流。单元测试

什么去了哪儿?

尽管理解MVC的理论很容易,有时候在实际的场景指出什么去了哪儿倒是比较复杂的。让咱们花些时间关注一下。测试

视图层

当一个用户和你的App交互的时候,他们是在和视图层交流。视图被认为是App中的“哑吧”部分,由于它不该该包含任何的业务逻辑。在代码层面,你一般会看到:动画

UIView子类。从基本的UIView子类到复杂的自定义UIControl。代理

一个UIViewController(有争议)。因为一个UIViewController和它本身的根视图以及不一样的生命周期强烈的耦合在一起,我我的认为应该属于这一层,可是并非全部人认同。cdn

动画和控制器转场。

UIKit/AppKit、Core Animation 和 Core Graphics的一部分。

不要为了节省时间把一堆代码都写到UIViewController里,之后你可能会花多倍的时间来找bug,或者复用里面的代码。

用下面的清单检查你的视图层

它和模型层交互了吗?

它是否包含了任何的业务逻辑?

它是否作了和UI无关的事情?

若是上面任何一个问题的答案是yes,那么你就可能须要清理一下并重构了。

固然,这些规则没有被刻在石头上,有时你得弯曲它们。尽管如此,你得展示足够的重视。

控制器层

控制器层是app里最少复用的部分。由于它引入了你特定领域的规则。有些东西在你的app里有意义,可是在别人的app里面可能没有什么意义,这并不使人吃惊。

一般你会看到这一层的类决定着下面这些事情:

什么应该首先进入:持久化仍是网络?

你应该多久刷新一次app?

下一屏应该是什么,在什么样的情况下?

若是app进入后台,什么应该被清理掉?

你应该把控制器看作app的大脑:它决定接下来发生什么。一般你会想要对这些类作大量测试以确保全部的事情按照预期运行。

建议老是让控制器是可注入的。这样,你的UIViewController的拥有者就能提供控制器。这有两方面的好处:

一、便于测试。

二、这些层会很干净,而且去耦合。这有助于定义职责,从而造成总体上更健康的代码基础。

模型层

模型层并非像它看起来的那么可以自解释。

就如同你指望的那样,它将包含你的模型对象,基本覆盖了大部分层的界面。

MVC: Massive View Controller?

UIViewController过多的承担并不属于它的职责,最终致使Massive View Controller。它开始于积累像网络请求和数据解析这样的事情,最终愈来愈大以致于你失去了对信息流的追踪。更糟糕的是,你不能以一种安全的方式进行重构。由于这种方式会让单元测试变得很是困难。

针对臃肿的控制器的解决方案很难快速找到解决方案。所以它经常变成技术债务。这在iOS社区很常见,也是MVC名声被搞坏的缘由。可是这不是你的命运!

做为一个通常原则,一个UIViewController不该该拥有超过130行代码。这彷佛很那实现,可是若是你坚持原则,这很容易。如下是我坚持的一些原则:

一、view controller里的大部分代码和它的根视图UIView的自定义有关。

二、它应该负责把控制器和它的根视图勾连起来,例如,在一个IBAction上调用控制器方法。

三、UITableDataSource, UITableViewDelegate和其余的一些代理不该放在它里面。若是这样作,就没办法测试它们。

四、若是你的view controller里有过多的属性,你能够把他们分开到多个控制器中,或者建立一个自定义的UIView。

这些只是指导方针。有时你的UIViewController很是简单,可能就不必建立那么多实体。

记住,你赋予view controller的每个职责都会让你丧失测试和复用那段代码的机会。

相关文章
相关标签/搜索