iOS开发基础:苹果的MVC模式
MVC模式我们谈得够多了,但总有一些争议,比如RAC说明文档里关于MVC的描述是这样的:
来自ReactiveCocoa项目
斯坦福大学的iOS公开课第一课:
来自斯坦福公开课
中文维基百科上MVC条目的配图:
来自中文维基百科
乍一看,以上都是三角形,都描述了Model、View、Controller三者的关系,Controller都处于View与Model的中间位置。
这里再明确一下MVC的基本定义:
MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
- (控制器 Controller)- 负责转发请求,对请求进行处理。
- (视图 View) - 屏幕上显示的UI,响应用户事件,接受用户输入。
- (模型 Model) - 程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。
简单的说,MVC只是定义了一个面向对象的软件系统里,各个对象的角色。
三者概念并不难理解,难点在与这三者的交互关系,上面各方展示的关系里(线条表示),最大的差别在与Model 与 View 的关系,除了斯坦福那幅图,其它都建立了View与Model 之间的联系,无论间接还是直接。实际开发中,给一个TableViewCell 传递一个“Model”,也是常见做法。
但是,这样对吗?
这里我们想一下面向对象设计的目的:
面向对象的重要特性是封装,而封装的目的在于复用
比如一个阅读APP中,图书列表一个典型的TalbleViewCell是这样的:
来自多看阅读
这时,给这个TableView的Cell传递一个Book的Model对象,是很自然的,而且显得很方便,毕竟Cell要展示的封面图片、书名、简介、作者,Book对象都能提供。
再看另一个APP:
来自MUJI PASSPORT
注意到,其实Cell的布局是很相似的
iOS开发基础:苹果的MVC模式试想一个综合类购物app,同时提供书籍和服装列表,给cell传book还是cloth类,都不合适,而是直接需要图片的传图片,需要文字的传文字:
// 注意这里是伪代码
if object is class book
cell.image = object.coverImage
cell.title = object.title
else if object is class cloth
cell.image = object.image
cell.title = object.productName
我们看下苹果官方如何描述mvc三者的关系:
来自苹果开发文档
可见,
苹果的定义是View 与 Model 彻底分离,换句话说,这两者并不知对方的存在!
再注意下斯坦福的示意图,View 与 Model 之间是双实线,
iOS开发基础:苹果的MVC模式考过驾照的童鞋都知道其含义是 不要越界,
只有这样,才能定义出可复用的对象,也符合了面向对象编程的初衷:抽象
MVC是Cocoa 框架的核心,苹果要求任何类,必须是这三种角色之一。