再谈MVVM

前言

MVVM设计模式自2005年被微软提出以来,在应用开发领域获得了长久的发展。iOS开发过程中,Apple推荐的MVC模式,因其广泛诟病的massive viewcontroller,逐渐被解耦更充分的MVVM替代。
本质来说,MVVM跟MVC同属于MV(X)类型的模式,是解决开发中model层与UI层解耦的方案。MVVM的优点在于,通过架设viewmodel层(提供连接model和view层的中间件),解决了model和view在MVC controller(MVC中的C)的耦合。
MVVM的原理和优点不在赘述,参见概念图:


MVVM.png

Problem

考虑上图的左侧(view与viewmodel解耦):在实际使用过程中,通过viewmodel与view层状态量绑定,很好的解决了view层耦合,解放了viewcontroller,使其更专注于view的组合和管理。同时,viewmodel对model的更新和监听,转化为view层状态量的处理,使我们可以在viewmodel专注于view层页面量数据更新。
再考虑上图右侧:我们通常习惯于在viewmodel层来处理model数据,随着业务的增多,viewmodel中充斥了接口的调用、model的转化、数据的拼装,再加上对view层页面量的转化,viewmodel同样面临着massive化的问题
另外,viewmodel处理的model层数据越多,也代表着viewmodel与model的耦合度不断上升。某些数据可能会涉及到session维护,即数据也有着生命周期的管理,例如TCP长连的推送,历史数据和当前数据管理等等。那么对于这些可独立的操作,这一块model层数据处理,也具有复用的需求,不能够单单由viewmodel层来处理。
所以说,viewmodel massive化的问题,需要考虑到与model层更好的解耦。

Thinking

结合上图MVVM的定义,viewmodel与view层的关系,是通过状态量的绑定,实现data和action的binding;viewmodel与model层的关系,是更新和监听。
如果viewmodel不直接处理model的获取和转化,而是将复杂的model处理独立出去,然后采取类似viewmodel与view层binding的方式,是否可以实现viewmodel与model的更进一步解耦?

Solution

实现viewmodel与model进一步解耦,一个方案是,在中间架设datacontroller层。如图:


屏幕快照 2020-04-14 上午10.31.15.png
  • viewmodel拥有datacontroller,通过对datacontroller的data binding,监听处理过的data,并将data处理为view层页面量;
  • datacontroller拥有model,通过接收viewmodel发出的action,对model进行update,同时监听model数据变化,对model数据进行维护、转化和处理;
  • view层拥有viewmodel,通过对viewmodel的binding,完成view层页面量的刷新。
notice
  • viewmodel与datacontroller需有明确的分工。datacontroller的架设,是为了解耦model层数据处理逻辑,是以model层业务功能为导向的,viewmodel中涉及view层数据的处理,不应归并到datacontroller来处理,而是viewmodel层配合datacontroller来处理数据。
  • viewmodel和datacontroller虽是拥有关系,但并非强关联。datacontroller同样可以被其他viewmodel使用,是独立的数据处理组件。
  • 理解几个data:viewmodel里的data,是页面状态,面向页面显示的数据;datacontroller里的data,是model数据经过处理后的,面向业务的数据;model里的data,是面向接口的数据层数据。
scene

以行情类APP中的个股详情界面为例。个股详情界面,包含股票的盘口信息,分时走势图,K线图,成交明细,买卖五档等多个功能,这些数据的处理是非常复杂的。同一个功能的数据,可能需要多个接口返回进行拼装。以K线图为例,会要求历史数据和当日数据拼装,并通过TCP实时接收服务器推送的最新一根数据。
考察此时datacontroller,需要完成以下几个功能:

  • 多个接口的请求管理。历史数据接口、当日数据接口,以及服务器主动推送。
  • session管理。管理TCP推送,以及如果推送断掉后的主动定时刷新。
  • model层数据处理。将各个接口返回数据,转化为业务需求数据,例如K线数据拼装、校准、容错。
  • 数据源切换。行情数据服务可能存在多个行情源,例如普通行情服务和level2服务,行情源不同。需要datacontroller完成数据源切换,以及对应数据model的转换。输出到viewmodel层的data保持统一。

从以上场景可看出,如果没有datacontroller层,大量数据处理会耦合到viewmodel,一方面造成viewmodel的难以维护,另一方面很多处理逻辑是可独立可复用可单元测试的。

discussion

  1. 结合flux(react)的数据驱动模式
    datacontroller层的架设,实际上也是数据驱动的一种实践。viewmodel通过监听datacontroller,完成数据驱动,最终更新页面状态。
    更进一步,可以尝试结合flux(react)思想,设计datacontroller的具体实现。目前我的项目中,通过将flux思想引入datacontroller层,将各个接口实现转换为对应的action和reducer,采用组合的设计模式,自由组合各接口调用。接口返回的数据,区分为业务state,viewmodel通过监听这些state,完成数据层的监听。
    react是前端开发的主流框架之一,然而对APP开发来说,由于view更新机制的不同,react state更新的方式并不能很好的体现APP开发的性能。但在数据层,react单向数据流的思想还是值得借鉴,特别是对于业务数据复杂的功能,能够较好地管理数据更新。
  2. datacontroller与viewmodel同级的设计
    很早之前有一种MVVM设计,datacontroller层与viewmodel层同级,同为viewcontroller拥有。如下图:


    1452138195768694.png

这种设计更体现出datacontroller层的独立性。但正如作者所说,频繁的在 DC-VC-VM 里来回传递信息,会造成了大量胶水代码。且datacontroller直接暴露到viewcontroller,不利于view层与model层解耦。

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

推荐阅读更多精彩内容