iOS中使用MVC会使得ViewController臃肿吗?

什么是MVC?

MVC实际上是一种三层架构思想,将应用程序大体上分为三层View、Model和Controller层。MVC模式定义了这些类型的对象在应用程序及其通信线路中扮演的角色。在设计应用程序时,一个主要步骤是为属于这三组中的对象选择或创建自定义类。这三种类型的对象都通过抽象的边界与其他类型的对象分离,并跨越这些边界与其他类型的对象进行通信

  • View:是视图层,负责展示Model层的数据,并允许用户编辑Model中的数据。View不应该负责存储它所显示的数据。(当然,这并不意味着View永远不会实际存储它正在显示的数据。出于性能原因,View可以缓存数据或执行类似的技巧)。
  • Model:是业务层,负责保存应用程序的数据并定义操作该数据的逻辑。将数据交给View层展示。
  • Controller:充当应用程序的View层和Model层之间的中介。Controller通常负责确保View能够访问它们需要显示的Model对象,并充当View了解模型更改的管道。Controller对象还可以执行应用程序的设置和协调任务,并管理其他对象的生命周期。
    Cocoa的MVC.jpg

    更多内容参考iOS中的MVC

关于iOS中Controller和ViewController关系

在MVC中,Controller的作用在于让View和Model隔离,也就是解耦。Controller因为负责特定的View和Model的通信,所以通常来说是不能复用的,当然在某些时候也是能够复用的,看具体业务。

在iOS中,我们通常使用ViewController相关的自定义对象来作为Controller层的对象。所以,很多人会自然而然的认为ViewController就是Controller,但是这显然是不正确的。从前面对MVC的描述来看,Controller它是一个层,它是MVC中的C层,它并不指定是某个类某个对象,而ViewController通常是iOS里面我们继承自UIViewController自定义的类的对象,显然ViewController是不等于Controller的。ViewController在某种程度上是一个角色合并的对象,同时具有Controller和View的角色,这也是为什么在iOS中很多人经常出现的ViewController过重的问题。

使用MVC会导致ViewController臃肿吗?

为什么会臃肿?

很多人在iOS中使用MVC为什么ViewController会变重?其实就是因为在iOS中ViewController是页面得一个基本单位,大部分正常情况下,一个页面会有一个ViewController,由于ViewController是一个角色合并的对象,iOS中ViewControler不但要管理视图层级和管理对象生命周期,还要负责View和Model之间的通信。而很多人为了方便,甚至把Model相关的业务逻辑都放在ViewController 来实现,导致ViewControler任务过于繁重。综上所述,ViewController变重的我觉得主要有如下两点原因:

  • 第一点可能是把View和Model相关的业务都让ViewController来实现了;
  • 第二点就是页面很复杂,需要管理的View和Model比较多,导致ViewController代码很多。

对于第一点,这显然是违反MVC框架的初衷的。Controller层应该只是扮演中介者和协调者的角色,而这里面实际上ViewControler不只是扮演Controller的,还同时拥有View和Model的角色,承担了很多不该属于自己的任务。而对于第二点,我觉得这不是MVC本身的问题。实际上如果某个类或者说某个模块本身功能比较复杂,那么代码量相应的比较多是正常的,这个跟使用什么框架没有关系。

如何解决臃肿的问题?

类似ViewController这样的臃肿问题,其实主要是因为在使用过程中没有定位清楚,在一个类上添加各种各样的功能,耦合性很大。这不仅维护起来很麻烦,也很难复用。如果我们将这些功能分别用不同的类或分类来实现,进行解耦,后期的需求变更和维护就会互不影响,还能够降低类的复杂度,提高可读性,总的来讲就是一个类、接口、方法只负责一项职责。这其实也是所谓的模块化,对于面向对象语言,我们本就应该习惯于进行模块化开发,把一个臃肿的类或对象再次细分成不同的模块,细分模块可以是自定义新的类,也可以使用分类(Category)。

何时使用其他类?何时使用分类?
这主要根据业务需求来看,我认为一个比较简单的标准就是,细分出的子模块是否可以被与当前类无关的其他类所复用,如果可以被其他类所复用,那显然自定义新的类比较合适;如果当前的子模块只被当类或其子类使用,显然使用分类更加合适。

使用MVVM就能解决ViewController臃肿的问题?

经常听有人说,使用MVVM就能解决ViewController过重的问题。其实我觉得这是一个伪命题。就像前面分析的那样,MVC本质就是三层框架思想,Controller是一个层级,它不是指某个类,简单说就是ViewController不等于C,它只是C的一部分。对于ViewContrller臃肿的问题,我觉得不能归咎于MVC的问题,实际如果我们的代码不进行模块化,你的View、Model层、也包括你使用MVVM的VM层都有可能出现臃肿的问题。所以本身某个类出现代码臃肿的问题不是因为你使用了什么框架,而是你怎么编写代码的问题。

不管所谓的MVC、MVP或者MVVM,它们其实就是一种分层思想,将代码结构按层次进行划分、然后通过中间层进行解耦。目的只是在于层间解耦,并没有强调某一层由某个类来实现。不同的层内部又可以按照业务需求分成不同的模块,不同的模块又可以分成不同子模块。就像前面说过,在iOS中使用MVC,不要把C层等同于UIViewController及其子类,C层可以不止包含ViewController,还有可以有其它的类来分担。

说到这里,顺便说一个问题。为什么在iOS使用MVC很少有人说View臃肿或者Model臃肿?这其实很简单,因为习惯上我们在面对复杂View的时候一般都会把View层分成不同的子View来实现,这其实就是一个很好的模块化的例子。Model层也一样。但是Model还有一个问题,就是很多人经常把数据模型Model误认为是MVC的Model层,导致的问题就是仅限于把M当做数据层,但是回过头来看的话,M层在MVC中的定位是业务层,它是负责保存应用程序的数据并定义操作该数据的逻辑,然后将数据交给View层展示的。如果我们仅仅把M层当做数据层的话,那么就容易少了一个定义数据操作的业务层,所以就出现了我们前面说的,在iOS中很多人把业务层代码都写到ViewController导致臃肿的问题。

在iOS中使用MVC的一些代码实践

ModelController

针对iOS的MVC中,因为ViewController的角色合并导致在使用上出现混淆的问题,与之相对应创建一个ModelController对象。这个ModelController的定位具有了部分Model和Controller的功能。

这样我们就可以把ViewController看着主要关注View层的Controller,它"拥有"View,管理View相关的逻辑以及View和Model的通信;而ModelController是一个主要关注Model层的Controller。它“拥有”Model,负责定义Model的相关操作方法,把数据交给View层展示,并可以根据View层的事件操作Model。

代码结构分析

根据前面的分析,在代码编写时,我们采用了如下图所示的结构:


MVC.jpg

这里View层和Model层原来的角色不变,我们把Controller分为ViewController和ModelController两个部分。

  • ViewController是页面得基本单位,管理者当前页面相关对象的生命周期,包括View和ModelController对象,正常情况下每个页面一个ViewController,每个ViewController可以拥有多个View,同时一个ViewController拥有一个或多个ModelController;
  • ModelController用于管理当前view的需要显示和操作的Model,一个ModelController拥有一个或多个Model,ModelController持有View需要展示的数据,通过ViewController交给View显示。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容