iOS开发中MVC与MVVM

一、原始MVC

iOS中的MVC(Model-View-Controller)将App架构分为Model、View、Controller三部分。简单说:

  1. Model数据模型,负责数据管理,将数据存储至本地数据库中。

  2. View展示层,负责对Model持有的数据进行展示。

  3. Controller控制者,负责协调处理Model与View之间的数据及触摸事件,Model与View不会直接沟通,都是依靠Controller来同步两者的数据显示。

将上面的描述可以归纳为下面的图示:

效果

iOS中的MVC还有另外一个雅称:Massive ViewController。重量级的ViewController,是指ViewController文件中包含了成千上万行的代码,这些代码的由来主要包括:网络请求、事件响应处理、业务逻辑、本地数据库操作、工具类方法等等。正是这些代码,让ViewController变得臃肿,甚至最后难以维护,项目的推进举步维艰。

二、MVC过渡期之瘦身ViewController,让Model变胖

原始的MVC模式有一个问题,就是Massive ViewController的问题。为了解决这个问题,衍生出了胖model。什么是胖model?就是包含数据属性变量的同时,还会有弱业务的方法代码,比如根据年龄算出生日期,生肖属相什么的。这样就把原本放在ViewController里面的弱业务代码移到model里面,给ViewController减负,将功能细分的更清楚。

三、MVVM

iOS中的MVVM是MVC的一个衍生版本。主要是在MVC的基础上,将逻辑复杂的胖Model的功能拆分成了ViewModel和瘦Model;也可以说是把原先ViewController里面的复杂数据逻辑独立成ViewModel模块。如下图演示效果:

效果

上面图表达的含义主要是:VM和V之间是通过C模块来协调,VM和V有对应关系。所以MVVM更形象的表达式:M-VM-C-V的结构。

ViewModel的主要职能是负责数据处理。将原先的业务逻辑尽可能的搬到了ViewModel模块来实现,并且将实现的结果展示在View上。但是这里的View和ViewModel彼此是不清楚对方的存在的,可以通过ReactiveCocoa的方式实现控件属性(ViewModel)与控件(View)的之间松散绑定,而controller里面就是实现View与ViewModel之间的绑定代码。

举个栗子:现在写一个网络下载的app,我们可以将下载的代码封装在Download模块里,属于网络层下载模块,该模块可以发起网络下载请求,并实时更新下载进度,我们可以将Download模块放到ViewModel中的beginDownloadTaskWithURL:方法中去启动下载,并实时更新ViewModel中的当前下载进度的属性,通过ReactiveCocoa将进度条的ProgressValue与当前下载的进度绑定即可。不需要关心下载进度改变后,该如何去刷新进度条的ProgressValue值。用户发起暂停下载的触摸事件,通过ViewModel的pauseDownloadTask方法来暂停Download模块的下载逻辑,并处理保存相关状态。

效果

通过上面的描述以及图示,再看看M-VM-C-V结构的各自职责:

总结

上面说到的关于iOS客户端的架构设计,是相对的说法,在具体的开发中,应结合实际的情况,对其中的结构模块可以进行功能迁移调整。但一定要做到以下几点:

一、结构松散,不要牵一发而动全身

涉及到后期的维护,功能模块的方便搬迁到其它项目中。切勿图一时之快而不关心具体的结构,随便找个舒服的地方,舒服的方式写下让后来者觉得可怕的代码。

二、各司其职,切勿越俎代庖

模块的功能明确,如果出现了越俎代庖,超越自己职责范围去处理事宜时,就要考虑是不是模块功能在划分时出了问题,需不需要独立一个全新的模块来做这样一件事。

三、善假于物,避免闷头重复造轮子

遇到架构上的问题,需要考虑是否可以用现有的知识去解决,使用合理的设计模式,远比自己用拙劣的代码去解决问题要好的多。所以熟练掌握软件开发中的GOF设计模式是非常有必要的。


参考链接:

iOS应用架构谈_view层的组织和调用方案

MVVM介绍

文章来自 http://skymonkey.cn/

高能广告区

暂无广告哦=^^=。继续看看其它文章吧!