MVVM的两种不同思路

思路1:7种不同角色

  • xxxViewController处于最顶级,作为调用者
  • xxxViewxxxViewModel作为xxxViewController的属性。一个负责界面显示,一个负责具体业务。xxxViewModel的主要作用是给xxxViewController减负,全面接管他的工作。这一步是MVVM思想的最大体现,看似最简单,其实最关键。以后凡事找xxxViewModel,跟xxxViewController基本上没啥关系了。(数据、业务和界面解耦了)
  • xxxUseCase作为xxxViewModel属性,完成xxxViewModel的具体工作,比如网络请求,相关业务逻辑等等。
  • xxxBuilder作为xxxUseCase的属性。主要作用是将数据xxxModel转换为适合xxxView显示的数据xxxViewBean。一般来讲,xxxModel可以作为xxxBuilder的输入参数,xxxViewBean作为xxxBuilder的返回值。
  • xxxUseCase通过xxxBuilder得到相应的xxxViewBean之后,需要更新xxxView的显示。这里的方法是通过xxxViewModel,将weak修饰的xxxViewController传过来(防止引用循环),通过他,访问相应的xxxView,利用新得到的xxxViewBean进行更新。
  • xxxViewController、xxxView、xxxViewModel、xxxUseCase、xxxBuilder、xxxModel、xxxViewBean有7种不同的角色。
  • 其他地方说的ViewModel和这里说的ViewBean有点类似。

思路2:4+1种不同角色

  • xxxViewController处于最顶级,作为调用者,同时也是被“减负”的对象
  • xxxView作为xxxViewController的属性,负责界面显示
  • xxxViewModel作为xxxView更新界面相关方法的参数,其构造方法的参数是xxxModel(可以为nil,提供默认静态显示状态)。xxxViewModel的作用是显示逻辑,对xxxModel的一次适配。这一步很简单,不过确实这里两个关键点中的一个。将原先的一些琐碎的显示逻辑从xxxViewController中转移过来。
  • yyyServicexxxViewController提供数据和业务服务。其服务对象是业务模块中的所有ViewController,多个复用。等业务成熟之后,可以隔离为yyyService.framework。调用接口,统一为类方法,具体实现是单例还是其他实例,对外部隐藏。
  • yyyService服务的返回值是xxxModel,他没有必要知道xxxViewModel的任何信息。这一步也很关键,将数据和业务逻辑和界面、ViewController解耦。
  • xxxViewController的作用是一个“调用者”。调用yyyService得到xxxModel。调用xxxView更新界面。xxxView通过xxxModel得到相应的xxxViewModel,更新显示。
  • xxxViewController、xxxView、xxxViewModel、xxxModel有4种不同角色。再加上多个共用的yyyService,一共5种不同角色。
  • 双向绑定,swift只要用属性观察器就可以了;Object-C可以采用第三方库ReactiveCocoa

隔离出一个逻辑层

  • 对于业务逻辑,采用zzzLogic的命名方式,作为第二层的抽象。这样就分为界面,逻辑,服务三层。层与层之间用协议进行沟通,通过framework进行隔离。
  • 推荐用Swift开发,一些好的特性不可获取。至于runtime,c++,c等,可以在一个framework中用Object-C作为胶水过渡一下
  • 在开发界面的时候,以ViewModel和逻辑协议与逻辑层沟通。协议定好之后,马上提供默认实现。这样整个过程就能独自前进。
  • 逻辑层实现界面要求的协议,不能访问任何UIKit的对象,同时将一些跟具体业务逻辑没有关系的功能型问题下放给服务层,定好协议,马上提供默认实现。文件组织按照业务角度划分模块,不要考虑具体的页面。(不然的话,两套标准,必然混乱)
  • 服务层就负责实现逻辑层定好的协议。按照功能分模块,不要带入任何界面和业务逻辑的概念,只按照功能一个标准组织结构。(标准不统一,必然带来混乱)
  • 在文件命名上,禁止使用temp、core、common、public、base、tool等抽象的名字,作为后缀可以考虑。
  • tableView这种界面和数据强绑定的方式需要引入协议的方式,将界面和数据分开
  • SDWebImage这种在UI上扩展数据功能的第3方库要换掉,或者改变使用方式。能干好下载一件事就可以了,不用瞎操心界面的显示
  • 类别这种方式不要直接用,中间在包一层,以函数接口的方式对外提供服务。统一到类方法的包装之中,简单好用。
  • 界面更新采用属性观察者模式,集中到观察ViewModel的变化上来,进行单向的数据绑定
  • 反向通信以block的方式为主,一对一,关系简单,使用灵活
  • 正向通信以函数返回值为主,多个值可以返回一个元组,很方便的
  • 函数参数以copy形式的形参为主,改变实参的inout参数尽量不要用
  • 在必要的时候,可以用用notification,这个要注意通知都要求在主线程发送和接收,降低复杂度,减少不必要的麻烦
  • 界面跳转采用url的形式统一编码,集中在一个文件中定义。具体的跳转实现在各自的controller中,不要用统一的switch结构
  • 库管理工具推荐Carthage,当然cocoapods也很好用,看习惯选择。
  • 环境参数也放在一个统一的plist文件中,比如友盟的APPKey,baseURL
  • 对于支付插件,分享等外接组件,统一用framework再包一层,对外提供自己定义的协议接口。不能让具体的功能实现污染统一的接口定义。
  • 界面层有需要的时候也能够访问服务层。
  • 访问顺序是单向的,不能反过来,比如服务层不能方位逻辑层和界面层;逻辑层也不能访问界面层。
  • 在必要的时候,逻辑层或者服务层能够使用界面层传过来的UI对象,但是应该采用weak引用,不能持有该UI对象。UI对象的生命周期由界面层独立负责。
  • 真正的数据驱动应该在逻辑层,界面层只是简单的界面流转,不要带入数据和业务逻辑。就像故事版的连线一样,被动流转,不主动驱动。

备注

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

推荐阅读更多精彩内容