MVVM奇葩说

转载请注明出处:http://www.olinone.com/

一直想聊聊这个话题,也有朋友跟我留言,让我讲讲MVVM,只可惜一直没整明白,不敢轻易下笔。针对MVVM,网上有很多不错的文章,比如MVVM介绍被误解的 MVC 和被神化的 MVVM以及Look at MVVM from a different perspective等等

文章前我想先提几个问题

1、MVVM到底是什么?它和MVC有什么区别?

2、MVVM中VM到底是个什么角色?它和Controller或者Manager有什么区别?

3、ViewController在MVVM中扮演怎样角色?Api数据请求放在哪里?数据流向如何?

MVVM简介

关于MVVM,相信大家或多或少都有了解。引用MVVM介绍文中一图

受MVC或MVP架构的影响,对MVVM最初印象以为这是一个以ViewModel为核心,处理View和Model的开发架构。于是乎在原有MVC的基础上,创建了一个所谓的ViewModel对象,然后把ViewController中的代码移到ViewModel中,在ViewModel里面处理View以及Model的所有逻辑。毕竟大家都在说MVVM可以为ViewController瘦身,这ViewController就剩创建ViewModel的代码,嗯,够瘦身,这就是MVVM!

慢慢的,发现有什么地方不对,哪里不对?第一想法就是ViewController的定位,View?不是,Controller?也不是!毕竟它就创建ViewModel,好像与View、Model也没啥关系。抛开ViewController不谈,突然发现这样的ViewModel、Model以及View不就是MVC,一个以ViewModel为中心的MVC!

错在哪里

核心问题就在于对ViewModel角色的定位不清!基于MVVM设计思路,ViewModel存在目的在于抽离ViewController中展示业务逻辑,而不是替代ViewController,其它视图操作业务等还是应该放在ViewController中实现

既然不负责视图操作逻辑,ViewModel中就不应该存在任何View对象,更不应该存在Push/Present等视图跳转逻辑。因此,ViewModel中绝不应该存在任何视图操作相关的代码

@interface ViewModel : NSObject

// viewmodel中切不可存在view对象,更不该出现push或者present代码

- (instancetype)initWithTableView:(UITableView *)tableView;

@end

ViewModel做啥

很简单,处理视图展示逻辑,ViewModel负责将数据业务层提供的数据转化为界面展示所需的VO。其与View一一对应,没有View就没有ViewModel

比如,数据业务层传递一个含有性别属性sex的DO对象,0表示男, 1表示女。ViewModel的职责就是将其转化为展示层可显示的VO对象

self.personVO.sex = personDO.sex == 0 ? @"男": @"女";

ViewModel和View一起组成DDD(Model-Driven Design)领域驱动架构体系中的Presentation展示层。在iOS中,数据流向可以表示为ViewModel->ViewController->View,ViewController负责连接VO及其对应的View对象

领域驱动设计

领域驱动设计(DDD)对于安卓童鞋可能非常熟悉,有兴趣的童鞋可以参考这篇文章,本文不做过多讲解,借用其描述介绍几个名词

1、VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来

2、DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体

3、PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应PO的一个(或若干个)属性

4、Domain:领域驱动层,是用户与数据库交互的核心中转站,控制用户数据收集,控制请求转向等

MVVM架构中,ViewModel连接视图View和数据业务Model层,而Domain和Data数据持久层共同组成整个Model层。完整结构如图所示

Model并不表示Model

MVVM架构中的M,并不表示Model对象,而是表示整个数据业务层,对应DDD架构中的Domain层以及数据Data层。业务开发中,一般考虑Api或者DB对象,极少考虑Domain层设计,也不会区分DO或者PO对象。笼统定义Model ,将其传递给展示层ViewModel,久而久之,Model对象承载的信息越来越多,更有甚者,在Model中处理业务逻辑,导致项目维护成本增加,代码中出现if..else的概率也会越来越大

@interface PersonModel : NSObject

@property (nonatomic, assign) NSInteger sex;

@property (nonatomic, readonly) NSString *sexDescription;

@end

@implementation PersonModel

// model中不应该存在业务逻辑代码

- (NSString *)sexDescription {

    return self.sex == 0 ? @"男": @"女";

}

@end

当然,Domain层并不是必须的,实际开发中,需要根据具体复杂度和需求来决定。比如只是纯粹的请求展示界面,设计过多的层次结构反而会增加项目的维护成本。同时,Domain层不应该存在任何状态变量!

Data数据层

ViewModel负责展示层逻辑,而Data层则对应数据层逻辑,一般以Manager或者Service身份存在,数据来源主要包括Api、DB或者Cache等。Data数据层操作对象主要为PO持久化对象,对象一旦创建,原则上不可修改

Data数据层具有独立可测试性,其不依赖视图层而存在。切记不可在Data层操作任何视图对象!

@implementation PersonDBAccess

// Data层不应该存在任何视图相关代码

- (NSArray *)fetchPersonModels {

    [SVProgressHUD showWithStatus:@"加载中。。。"];

}

@end

MVVM奇葩说

文章到此,想必各位对MVVM架构已经有了大致了解。对比安卓童鞋对MVP架构的钟爱,iOS童鞋也许更加青睐MVVM,拌上ReactiveCocoa或者RxSwift,这道菜可以做的更加绚烂多彩!当然,正如唐巧在文中所言:ReactiveCocoa 和 MVVM 不应该被神化,我们需要保持的是一个拥抱变化的心,以及理性分析的态度。在新技术的面前,不盲从,也不守旧,一切的决策都应该建立在认真分析的基础上,这样才能应对技术的变化!


写在文后:

为期两天的SwiftCon已经落幕,虽然离我只有两站地铁,只可惜依然没能前往聆听各位大师的技术分享,特别还有我同事兼朋友刘冠杉的个人首秀。虽然,现在网上也出现了各种不好的声音,但是我仍然相信,大多数分享者还是为此付出了不少心血,值得我们为之鼓掌!

个人技术的成长不在一朝一夕,而是长年累月的付出积累沉淀的结果!Swift3.0不久即将发布,而我个人也会逐渐转移☞对Swift语言的学习。与此同时,随着公司ReactNative项目的上马,我也会加强对RN技术的专研和学习中

感谢你的来访,你可以Follow我的个人GitHub,也可以关注我的新浪微博,下期再见!

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

推荐阅读更多精彩内容